Merge branch 'aamir_dev' into faiz_development_common

# Conflicts:
#	assets/langs/ar-SA.json
#	assets/langs/en-US.json
#	lib/generated/codegen_loader.g.dart
#	lib/generated/locale_keys.g.dart
#	lib/view_models/service_view_model.dart
aamir_dev
Faiz Hashmi 1 year ago
commit 04bcf76083

@ -705,6 +705,10 @@
"customerLocation": "موقع العميل", "customerLocation": "موقع العميل",
"deliveryAvailable": "التوصيل متاح", "deliveryAvailable": "التوصيل متاح",
"viewed": "تم المشاهدة", "viewed": "تم المشاهدة",
"updateUserDetails": "تحديث تفاصيل المستخدم",
"enterNewFirstName": "أدخل الاسم الأول",
"enterNewLastName": "أدخل الاسم الأخير",
"userDetailsUpdated": "يتم تحديث تفاصيل المستخدم",
"itemNoLongerAvailable": "لم يعد هذا العنصر متاحًا.", "itemNoLongerAvailable": "لم يعد هذا العنصر متاحًا.",
"reactivateAd": "إعادة تنشيط الإعلان", "reactivateAd": "إعادة تنشيط الإعلان",
"dealOutsideApp": "تمت الصفقة خارج التطبيق مع عميل آخر.", "dealOutsideApp": "تمت الصفقة خارج التطبيق مع عميل آخر.",
@ -741,6 +745,16 @@
"active": "نشط", "active": "نشط",
"paymentType": "نوع الدفع", "paymentType": "نوع الدفع",
"searchByCreatedDate": "البحث حسب تاريخ الإنشاء", "searchByCreatedDate": "البحث حسب تاريخ الإنشاء",
"cityNameMandatory": "المدينة إلزامية",
"genderMandatory": "الجنس إلزامي",
"updateCity": "تحديث المدينة",
"userGender": "جنس",
"userMale": "ذكر",
"userFemale": "أنثى",
"maxFileSelection" :"يمكنك تحديد الحد الأقصى لملفات 7",
"maxFileSize": "يجب أن يكون حجم كل ملف أقل من 2 ميغابايت",
"onlyJPGandPNG": "يُسمح فقط بملفات JPG وPNG",
"expiryDate": "تاريخ انتهاء الصلاحية",
"dealCompleted": "تم إتمام الصفقة", "dealCompleted": "تم إتمام الصفقة",
"theDealNotCompleted": "لم تكتمل الصفقة", "theDealNotCompleted": "لم تكتمل الصفقة",
"cancelRequest": "أريد إلغاء الطلب.", "cancelRequest": "أريد إلغاء الطلب.",

@ -760,4 +760,19 @@
"noteCopyItemsExplanation": "Note: You will be able to copy items from one service to another in a selected category. You must create the services first and they should be approved. Then you will be able to get the available services from which you can copy all or selected items.", "noteCopyItemsExplanation": "Note: You will be able to copy items from one service to another in a selected category. You must create the services first and they should be approved. Then you will be able to get the available services from which you can copy all or selected items.",
"requestCreatedOn": "Request created on", "requestCreatedOn": "Request created on",
"online": "Online" "online": "Online"
"searchByCreatedDate": "Search By Created Date",
"updateUserDetails": "Update User Details",
"enterNewFirstName": "Enter First Name",
"enterNewLastName": "Enter Last Name",
"userDetailsUpdated": "User Details is Updated",
"cityNameMandatory": "City is mandatory",
"genderMandatory": "Gender is mandatory",
"updateCity": "Update City",
"userGender": "Gender",
"userMale": "Male",
"userFemale": "Female",
"maxFileSelection" :"You can select a maximum of 7 files",
"maxFileSize": "Each file size must be less than 2 MB",
"onlyJPGandPNG": "Only JPG and PNG files are allowed",
"expiryDate": "Expiry Date"
} }

@ -4,6 +4,7 @@ import 'package:mc_common_app/models/subscriptions_models/provider_subscription_
import 'package:mc_common_app/models/subscriptions_models/subscription_model.dart'; import 'package:mc_common_app/models/subscriptions_models/subscription_model.dart';
import 'package:mc_common_app/models/user_models/user.dart'; import 'package:mc_common_app/models/user_models/user.dart';
import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
class AppState { class AppState {
static final AppState _instance = AppState._internal(); static final AppState _instance = AppState._internal();
@ -70,4 +71,13 @@ class AppState {
set setproviderSubscription(List<Subscription>? value) { set setproviderSubscription(List<Subscription>? value) {
_providerSubscription = value; _providerSubscription = value;
} }
DropValue? _userRegisterCountrySelection ;
DropValue get getUserRegisterCountrySelection => _userRegisterCountrySelection!;
set setUserRegisterCountrySelection(DropValue value) {
_userRegisterCountrySelection = value;
}
} }

@ -39,6 +39,7 @@ class ApiConsts {
static String logoutUser = "${baseUrlServices}api/Account/Logout"; static String logoutUser = "${baseUrlServices}api/Account/Logout";
static String updateUserImage = "${baseUrlServices}api/User_UpdateProfileImage"; static String updateUserImage = "${baseUrlServices}api/User_UpdateProfileImage";
static String getUserImage = "${baseUrlServices}api/ProfileImage"; static String getUserImage = "${baseUrlServices}api/ProfileImage";
static String userUpdate = "${baseUrlServices}api/User_Update";
static String providerComplaintCreate = "${baseUrlServices}api/ServiceProviders/ProviderComplaint_Create"; static String providerComplaintCreate = "${baseUrlServices}api/ServiceProviders/ProviderComplaint_Create";
//Profile //Profile
@ -255,6 +256,12 @@ class GlobalConsts {
} }
return appInvitationMessageEn; return appInvitationMessageEn;
} }
// Attachment Values
int maxFileCount = 7;
int maxFileSizeInBytes = 2 * 1024 * 1024;
} }
class MyAssets { class MyAssets {
@ -396,4 +403,6 @@ class SignalrConsts {
// General // General
static String sendMessageGeneral = "SendMessageGeneral"; static String sendMessageGeneral = "SendMessageGeneral";
static String receiveMessageGeneral = "ReceiveMessageGeneral"; static String receiveMessageGeneral = "ReceiveMessageGeneral";
} }

@ -44,6 +44,8 @@ import 'package:mc_common_app/views/user/register_page.dart';
import 'package:mc_common_app/views/user/register_provider_page.dart'; import 'package:mc_common_app/views/user/register_provider_page.dart';
import 'package:mc_common_app/views/user/register_selection_page.dart'; import 'package:mc_common_app/views/user/register_selection_page.dart';
import 'package:mc_common_app/views/splash/splash_page.dart'; import 'package:mc_common_app/views/splash/splash_page.dart';
import 'package:mc_common_app/views/user/update_user_city_country.dart';
import 'package:mc_common_app/views/user/update_user_details.dart';
import 'package:mc_common_app/views/user/vertify_password_page.dart'; import 'package:mc_common_app/views/user/vertify_password_page.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/widgets/image_viewer/image_viewer_screen.dart'; import 'package:mc_common_app/widgets/image_viewer/image_viewer_screen.dart';
@ -168,6 +170,8 @@ class AppRoutes {
//Chat //Chat
static const String chatView = "/chatView"; static const String chatView = "/chatView";
static const String updateUserDetails = "/updateUserDetails";
static const String updateUserCity = "/updateUserCity";
static const String initialRoute = splash; static const String initialRoute = splash;
static final Map<String, WidgetBuilder> routes = { static final Map<String, WidgetBuilder> routes = {
@ -187,6 +191,8 @@ class AppRoutes {
forgetPasswordMethodPage: (context) => ForgetPasswordMethodPage(ModalRoute.of(context)!.settings.arguments as String), forgetPasswordMethodPage: (context) => ForgetPasswordMethodPage(ModalRoute.of(context)!.settings.arguments as String),
changeMobilePage: (context) => ChangeMobilePage(), changeMobilePage: (context) => ChangeMobilePage(),
changeEmailPage: (context) => const ChangeEmailPage(), changeEmailPage: (context) => const ChangeEmailPage(),
updateUserDetails: (context) => const UpdateUserDetails(),
updateUserCity: (context) => const UpdateUserCityCountry(),
changePassword: (context) => const ChangePasswordPage(), changePassword: (context) => const ChangePasswordPage(),
editAccountPage: (context) => const EditAccountPage(), editAccountPage: (context) => const EditAccountPage(),
profileView: (context) => const ProfileScreen(), profileView: (context) => const ProfileScreen(),

@ -721,6 +721,10 @@ class CodegenLoader extends AssetLoader{
"customerLocation": "موقع العميل", "customerLocation": "موقع العميل",
"deliveryAvailable": "التوصيل متاح", "deliveryAvailable": "التوصيل متاح",
"viewed": "تم المشاهدة", "viewed": "تم المشاهدة",
"updateUserDetails": "تحديث تفاصيل المستخدم",
"enterNewFirstName": "أدخل الاسم الأول",
"enterNewLastName": "أدخل الاسم الأخير",
"userDetailsUpdated": "يتم تحديث تفاصيل المستخدم",
"itemNoLongerAvailable": "لم يعد هذا العنصر متاحًا.", "itemNoLongerAvailable": "لم يعد هذا العنصر متاحًا.",
"reactivateAd": "إعادة تنشيط الإعلان", "reactivateAd": "إعادة تنشيط الإعلان",
"dealOutsideApp": "تمت الصفقة خارج التطبيق مع عميل آخر.", "dealOutsideApp": "تمت الصفقة خارج التطبيق مع عميل آخر.",
@ -757,6 +761,16 @@ class CodegenLoader extends AssetLoader{
"active": "نشط", "active": "نشط",
"paymentType": "نوع الدفع", "paymentType": "نوع الدفع",
"searchByCreatedDate": "البحث حسب تاريخ الإنشاء", "searchByCreatedDate": "البحث حسب تاريخ الإنشاء",
"cityNameMandatory": "المدينة إلزامية",
"genderMandatory": "الجنس إلزامي",
"updateCity": "تحديث المدينة",
"userGender": "جنس",
"userMale": "ذكر",
"userFemale": "أنثى",
"maxFileSelection": "يمكنك تحديد الحد الأقصى لملفات 7",
"maxFileSize": "يجب أن يكون حجم كل ملف أقل من 2 ميغابايت",
"onlyJPGandPNG": "يُسمح فقط بملفات JPG وPNG",
"expiryDate": "تاريخ انتهاء الصلاحية",
"dealCompleted": "تم إتمام الصفقة", "dealCompleted": "تم إتمام الصفقة",
"theDealNotCompleted": "لم تكتمل الصفقة", "theDealNotCompleted": "لم تكتمل الصفقة",
"cancelRequest": "أريد إلغاء الطلب.", "cancelRequest": "أريد إلغاء الطلب.",
@ -1520,6 +1534,21 @@ static const Map<String,dynamic> en_US = {
"active": "Active", "active": "Active",
"paymentType": "Payment Type", "paymentType": "Payment Type",
"searchByCreatedDate": "Search By Created Date", "searchByCreatedDate": "Search By Created Date",
"updateUserDetails": "Update User Details",
"enterNewFirstName": "Enter First Name",
"enterNewLastName": "Enter Last Name",
"userDetailsUpdated": "User Details is Updated",
"cityNameMandatory": "City is mandatory",
"genderMandatory": "Gender is mandatory",
"updateCity": "Update City",
"userGender": "Gender",
"userMale": "Male",
"userFemale": "Female",
"maxFileSelection": "You can select a maximum of 7 files",
"maxFileSize": "Each file size must be less than 2 MB",
"onlyJPGandPNG": "Only JPG and PNG files are allowed",
"expiryDate": "Expiry Date"
"searchByCreatedDate": "Search By Created Date",
"dealCompleted": "The Deal Completed", "dealCompleted": "The Deal Completed",
"theDealNotCompleted": "The Deal Not Completed", "theDealNotCompleted": "The Deal Not Completed",
"cancelRequest": "I want to cancel the request.", "cancelRequest": "I want to cancel the request.",

@ -684,6 +684,10 @@ abstract class LocaleKeys {
static const customerLocation = 'customerLocation'; static const customerLocation = 'customerLocation';
static const deliveryAvailable = 'deliveryAvailable'; static const deliveryAvailable = 'deliveryAvailable';
static const viewed = 'viewed'; static const viewed = 'viewed';
static const updateUserDetails = 'updateUserDetails';
static const enterNewFirstName = 'enterNewFirstName';
static const enterNewLastName = 'enterNewLastName';
static const userDetailsUpdated = 'userDetailsUpdated';
static const itemNoLongerAvailable = 'itemNoLongerAvailable'; static const itemNoLongerAvailable = 'itemNoLongerAvailable';
static const reactivateAd = 'reactivateAd'; static const reactivateAd = 'reactivateAd';
static const dealOutsideApp = 'dealOutsideApp'; static const dealOutsideApp = 'dealOutsideApp';
@ -720,6 +724,16 @@ abstract class LocaleKeys {
static const active = 'active'; static const active = 'active';
static const paymentType = 'paymentType'; static const paymentType = 'paymentType';
static const searchByCreatedDate = 'searchByCreatedDate'; static const searchByCreatedDate = 'searchByCreatedDate';
static const cityNameMandatory = 'cityNameMandatory';
static const genderMandatory = 'genderMandatory';
static const updateCity = 'updateCity';
static const userGender = 'userGender';
static const userMale = 'userMale';
static const userFemale = 'userFemale';
static const maxFileSelection = 'maxFileSelection';
static const maxFileSize = 'maxFileSize';
static const onlyJPGandPNG = 'onlyJPGandPNG';
static const expiryDate = 'expiryDate';
static const dealCompleted = 'dealCompleted'; static const dealCompleted = 'dealCompleted';
static const theDealNotCompleted = 'theDealNotCompleted'; static const theDealNotCompleted = 'theDealNotCompleted';
static const cancelRequest = 'cancelRequest'; static const cancelRequest = 'cancelRequest';

@ -4,6 +4,8 @@
import 'dart:convert'; import 'dart:convert';
import 'package:mc_common_app/utils/enums.dart';
Document documentFromJson(String str) => Document.fromJson(json.decode(str)); Document documentFromJson(String str) => Document.fromJson(json.decode(str));
String documentToJson(Document data) => json.encode(data.toJson()); String documentToJson(Document data) => json.encode(data.toJson());
@ -37,26 +39,29 @@ class Document {
} }
class DocumentData { class DocumentData {
DocumentData({ DocumentData(
this.id, {this.id,
this.serviceProviderId, this.serviceProviderId,
this.documentId, this.documentId,
this.documentUrl, this.documentUrl,
this.status, this.status,
this.statusText, this.statusText,
this.comment, this.comment,
this.isActive, this.isActive,
this.document, this.document,
this.fileExt, this.fileExt,
this.documentName, this.documentName,
this.isLocalFile, this.isLocalFile,
}); this.description,
this.dateExpire,
this.isAllowUpdate,
this.isExpired});
int? id; int? id;
int? serviceProviderId; int? serviceProviderId;
int? documentId; int? documentId;
String? documentUrl; String? documentUrl;
int? status; DocumentStatusEnum? status;
String? comment; String? comment;
bool? isActive; bool? isActive;
String? document; String? document;
@ -64,20 +69,28 @@ class DocumentData {
String? statusText; String? statusText;
String? documentName; String? documentName;
bool? isLocalFile; bool? isLocalFile;
String? description;
String? dateExpire;
bool? isExpired;
bool? isAllowUpdate;
factory DocumentData.fromJson(Map<String, dynamic> json) => DocumentData( factory DocumentData.fromJson(Map<String, dynamic> json) => DocumentData(
id: json["id"], id: json["id"],
serviceProviderId: json["serviceProviderID"], serviceProviderId: json["serviceProviderID"],
documentId: json["documentID"], documentId: json["documentID"],
documentUrl: json["documentURL"], documentUrl: json["documentURL"],
status: json["status"], status: json.containsKey("status") ? (json['status'] as int).toDocumentStatusEnum() : null,
statusText: json["statusText"], statusText: json["statusText"],
comment: json["comment"], comment: json["comment"],
isActive: json["isActive"], isActive: json["isActive"],
dateExpire: json["dateExpire"],
isExpired: json["isExpired"],
isAllowUpdate: json["isAllowUpdate"],
document: null, document: null,
fileExt: null, fileExt: null,
documentName: json["documentName"], documentName: json["documentName"],
isLocalFile: false); isLocalFile: false,
description: null);
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
"id": id, "id": id,
@ -87,5 +100,27 @@ class DocumentData {
"status": status, "status": status,
"comment": comment, "comment": comment,
"isActive": isActive, "isActive": isActive,
"dateExpire": dateExpire,
"isExpired": isExpired,
"isAllowUpdate": isAllowUpdate,
}; };
} }
extension DocumentEnum on int {
DocumentStatusEnum toDocumentStatusEnum() {
switch (this) {
case 0:
return DocumentStatusEnum.needUpload;
case 1:
return DocumentStatusEnum.pending;
case 2:
return DocumentStatusEnum.review;
case 3:
return DocumentStatusEnum.approvedOrActive;
case 4:
return DocumentStatusEnum.rejected;
default:
throw Exception('Invalid status value: $this'); // Explicit handling for invalid cases
}
}
}

@ -60,6 +60,7 @@ class Subscription {
this.totalAds, this.totalAds,
this.branchesRemaining, this.branchesRemaining,
this.subUsersRemaining, this.subUsersRemaining,
this.subscriptionType,
this.adsRemaining}); this.adsRemaining});
int? id; int? id;
@ -81,6 +82,7 @@ class Subscription {
SubscriptionTypeEnum? subscriptionTypeEnum; SubscriptionTypeEnum? subscriptionTypeEnum;
bool? isMyCurrentPackage; bool? isMyCurrentPackage;
bool? isRenewable; bool? isRenewable;
int? subscriptionType;
int? subscriptionBranches; int? subscriptionBranches;
int? subscriptionSubUsers; int? subscriptionSubUsers;
@ -121,5 +123,6 @@ class Subscription {
branchesRemaining: json["branchesRemaining"], branchesRemaining: json["branchesRemaining"],
subUsersRemaining: json["subUsersRemaining"], subUsersRemaining: json["subUsersRemaining"],
adsRemaining: json["adsRemaining"], adsRemaining: json["adsRemaining"],
subscriptionType: json["subscriptionType"],
); );
} }

@ -25,14 +25,16 @@ class User {
int? messageStatus; int? messageStatus;
String? message; String? message;
factory User.fromJson(Map<String, dynamic> json) => User( factory User.fromJson(Map<String, dynamic> json) =>
User(
totalItemsCount: json["totalItemsCount"], totalItemsCount: json["totalItemsCount"],
data: json["data"] == null ? null : UserData.fromJson(json["data"]), data: json["data"] == null ? null : UserData.fromJson(json["data"]),
messageStatus: json["messageStatus"], messageStatus: json["messageStatus"],
message: json["message"], message: json["message"],
); );
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() =>
{
"totalItemsCount": totalItemsCount, "totalItemsCount": totalItemsCount,
"data": data?.toJson(), "data": data?.toJson(),
"messageStatus": messageStatus, "messageStatus": messageStatus,
@ -53,14 +55,16 @@ class UserData {
DateTime? expiryDate; DateTime? expiryDate;
UserInfo? userInfo; UserInfo? userInfo;
factory UserData.fromJson(Map<String, dynamic> json) => UserData( factory UserData.fromJson(Map<String, dynamic> json) =>
UserData(
accessToken: json["accessToken"], accessToken: json["accessToken"],
refreshToken: json["refreshToken"], refreshToken: json["refreshToken"],
expiryDate: json["expiryDate"] == null ? null : DateTime.parse(json["expiryDate"]), expiryDate: json["expiryDate"] == null ? null : DateTime.parse(json["expiryDate"]),
userInfo: json["userInfo"] == null ? null : UserInfo.fromJson(json["userInfo"]), userInfo: json["userInfo"] == null ? null : UserInfo.fromJson(json["userInfo"]),
); );
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() =>
{
"accessToken": accessToken, "accessToken": accessToken,
"refreshToken": refreshToken, "refreshToken": refreshToken,
"expiryDate": expiryDate?.toIso8601String(), "expiryDate": expiryDate?.toIso8601String(),
@ -69,34 +73,43 @@ class UserData {
} }
class UserInfo { class UserInfo {
UserInfo( UserInfo({this.id,
{this.id, this.userId,
this.userId, this.firstName,
this.firstName, this.lastName,
this.lastName, this.mobileNo,
this.mobileNo, this.email,
this.email, this.userImageUrl,
this.userImageUrl, this.roleId,
this.roleId, this.roleName,
this.roleName, this.genderID,
this.isEmailVerified, this.genderName,
this.serviceProviderBranch, this.isEmailVerified,
this.isVerified, this.serviceProviderBranch,
this.userRoles, this.isVerified,
this.isCustomer, this.userRoles,
this.isProviderDealership, this.isCustomer,
this.isDealershipUser, this.isProviderDealership,
this.providerId, this.isDealershipUser,
this.customerId, this.providerId,
this.countryId, this.customerId,
this.cityId, this.countryId,
this.dealershipId, this.cityId,
this.userLocalImage}); this.dealershipId,
this.userLocalImage,
this.cityName,
this.countryName,
});
int? id; int? id;
String? userId; String? userId;
String? firstName; String? firstName;
String? lastName; String? lastName;
String? countryName;
String? cityName;
int? genderID;
String? genderName;
String? mobileNo; String? mobileNo;
String? email; String? email;
dynamic userImageUrl; dynamic userImageUrl;
@ -130,6 +143,10 @@ class UserInfo {
userId = json["userID"]; userId = json["userID"];
firstName = json["firstName"]; firstName = json["firstName"];
lastName = json["lastName"]; lastName = json["lastName"];
cityName = json["cityName"];
genderID = json["genderID"];
genderName = json["genderName"];
countryName = json["countryName"];
mobileNo = json["mobileNo"]; mobileNo = json["mobileNo"];
email = json["email"]; email = json["email"];
userImageUrl = json["userImageUrl"]; userImageUrl = json["userImageUrl"];
@ -172,11 +189,14 @@ class UserInfo {
// dealershipId: json["dealershipID"], // dealershipId: json["dealershipID"],
// ); // );
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() =>
{
"id": id, "id": id,
"userID": userId, "userID": userId,
"firstName": firstName, "firstName": firstName,
"lastName": lastName, "lastName": lastName,
"countryName": countryName,
"cityName": cityName,
"mobileNo": mobileNo, "mobileNo": mobileNo,
"email": email, "email": email,
"userImageUrl": userImageUrl, "userImageUrl": userImageUrl,
@ -192,6 +212,8 @@ class UserInfo {
"providerID": providerId, "providerID": providerId,
"customerID": customerId, "customerID": customerId,
"dealershipID": dealershipId, "dealershipID": dealershipId,
"genderName": genderName,
"genderID": genderID
}; };
@override @override

@ -217,6 +217,7 @@ class BranchRepoImp implements BranchRepo {
"documentExt": documents[i].fileExt, "documentExt": documents[i].fileExt,
"documentImage": documents[i].document, "documentImage": documents[i].document,
"isActive": true, "isActive": true,
"dateExpire":documents[i].dateExpire,
}; };
map.add(postParams); map.add(postParams);
} }

@ -31,7 +31,7 @@ abstract class UserRepo {
Future<RegisterUserRespModel> basicVerify(String phoneNo, String otp, String userToken, {bool isNeedToPassToken = false}); Future<RegisterUserRespModel> basicVerify(String phoneNo, String otp, String userToken, {bool isNeedToPassToken = false});
Future<RegisterUserRespModel> basicComplete(String userId, String firstName, String lastName, String email, String password, {bool isNeedToPassToken = false}); Future<RegisterUserRespModel> basicComplete(String userId, String firstName, String lastName, String email, String password, String cityID, String genderID, {bool isNeedToPassToken = false});
Future<Response> loginV1(String phoneNo, String password); Future<Response> loginV1(String phoneNo, String password);
@ -55,6 +55,8 @@ abstract class UserRepo {
Future<GenericRespModel> changePassword(String currentPassword, String newPassword); Future<GenericRespModel> changePassword(String currentPassword, String newPassword);
Future<Map<String, dynamic>> updateUserInfo(String firstName, String lastName, String? city);
Future<ChangeMobileRespModel> changeMobileNoOTPRequest(countryID, String mobileNo, String password); Future<ChangeMobileRespModel> changeMobileNoOTPRequest(countryID, String mobileNo, String password);
Future<ConfirmMobileRespModel> changeMobileNo(String userToken, String userOTP); Future<ConfirmMobileRespModel> changeMobileNo(String userToken, String userOTP);
@ -104,12 +106,12 @@ class UserRepoImp implements UserRepo {
} }
@override @override
Future<RegisterUserRespModel> basicComplete(String userId, String firstName, String lastName, String email, String password, {bool isNeedToPassToken = false}) async { Future<RegisterUserRespModel> basicComplete(String userId, String firstName, String lastName, String email, String password, String cityID, String genderID, {bool isNeedToPassToken = false}) async {
Map<String, Object> postParams; Map<String, Object> postParams;
if (email.isEmpty) { if (email.isEmpty) {
postParams = {"userID": userId, "firstName": firstName, "lastName": lastName, "companyName": "string", "isEmailVerified": true, "password": password}; postParams = {"userID": userId, "firstName": firstName, "lastName": lastName, "companyName": "string", "isEmailVerified": true, "password": password, "cityID": cityID, "genderID": genderID};
} else { } else {
postParams = {"userID": userId, "firstName": firstName, "lastName": lastName, "email": email, "companyName": "string", "isEmailVerified": true, "password": password}; postParams = {"userID": userId, "firstName": firstName, "lastName": lastName, "email": email, "companyName": "string", "isEmailVerified": true, "password": password, "cityID": cityID, "genderID": genderID};
} }
String? t; String? t;
if (isNeedToPassToken) { if (isNeedToPassToken) {
@ -164,6 +166,11 @@ class UserRepoImp implements UserRepo {
return await injector.get<ApiClient>().getJsonForObject((json) => Country.fromJson(json), ApiConsts.getAllCountry); return await injector.get<ApiClient>().getJsonForObject((json) => Country.fromJson(json), ApiConsts.getAllCountry);
} }
// @override
// Future<Country> getAllCountriesForUser() async {
// return await injector.get<ApiClient>().getJsonForObject((json) => Country.fromJson(json), ApiConsts.getAllCountry);
// }
@override @override
Future<Cities> getAllCites(String countryId) async { Future<Cities> getAllCites(String countryId) async {
var postParams = { var postParams = {
@ -254,6 +261,13 @@ class UserRepoImp implements UserRepo {
return await injector.get<ApiClient>().postJsonForObject((json) => ConfirmEmailRespModel.fromJson(json), ApiConsts.changeEmail, postParams, token: t); return await injector.get<ApiClient>().postJsonForObject((json) => ConfirmEmailRespModel.fromJson(json), ApiConsts.changeEmail, postParams, token: t);
} }
@override
Future<Map<String, dynamic>> updateUserInfo(String firstName, String lastName, String? city) async {
var postParams = {"userID": "${AppState().getUser.data!.userInfo!.userId}", "firstName": "${firstName}", "lastName": "${lastName}", "genderID": 1, "cityID": city ?? 1};
String t = AppState().getUser.data!.accessToken ?? "";
return await injector.get<ApiClient>().postJsonForObject((json) => json, ApiConsts.userUpdate, postParams, token: t);
}
@override @override
Future<VerifyEmailRespModel> emailVerify(String email, String userID) async { Future<VerifyEmailRespModel> emailVerify(String email, String userID) async {
var postParams = { var postParams = {

@ -60,11 +60,11 @@ class CommonAuthImp implements CommonAuthServices {
return await localAuth.getAvailableBiometrics(); return await localAuth.getAvailableBiometrics();
} }
Future<void> getHuaweiAuth() async { // Future<void> getHuaweiAuth() async {
DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); // DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo; // AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
// if (androidInfo.brand == "HUAWEI") { // // if (androidInfo.brand == "HUAWEI") {
// huawei.canAuth(); // // huawei.canAuth();
// } // // }
} // }
} }

@ -4,8 +4,11 @@ import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart'; import 'package:geolocator/geolocator.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/main.dart'; import 'package:mc_common_app/main.dart';
import 'package:mc_common_app/utils/app_permission_handler.dart'; import 'package:mc_common_app/utils/app_permission_handler.dart';
import 'package:mc_common_app/utils/utils.dart';
abstract class CommonAppServices { abstract class CommonAppServices {
Future<List<File>> pickMultipleImages(); Future<List<File>> pickMultipleImages();
@ -55,21 +58,35 @@ class CommonServicesImp implements CommonAppServices {
return pickedFiles; return pickedFiles;
} }
@override
Future<List<File>> pickMultipleImages() async { Future<List<File>> pickMultipleImages() async {
final picker = ImagePicker(); final picker = ImagePicker();
final pickedImagesXFiles = await picker.pickMultiImage(); List<File> imageModels = [];
List<File> pickedImages = []; List<File> pickedImages = [];
if (pickedImagesXFiles == null) { var images = await picker.pickMultiImage(imageQuality: 70);
return [];
} for (var element in images) {
if (pickedImagesXFiles.isEmpty) { final extension = element.path.split('.').last.toLowerCase();
return [];
if (extension != 'jpg' && extension != 'jpeg' && extension != 'png') {
Utils.showToast(LocaleKeys.onlyJPGandPNG);
return [];
}
if (await element.length() > GlobalConsts().maxFileSizeInBytes) {
Utils.showToast(LocaleKeys.maxFileSize);
return [];
}
imageModels.add(File(element.path));
} }
for (var element in pickedImagesXFiles) {
pickedImages.add(File(element.path)); if (imageModels.length > GlobalConsts().maxFileCount) {
Utils.showToast(LocaleKeys.maxFileSelection);
imageModels = imageModels.sublist(0, GlobalConsts().maxFileCount); // Keep only the first 7 images
} }
pickedImages.addAll(imageModels);
return pickedImages; return pickedImages;
} }

@ -26,16 +26,8 @@ abstract class PaymentService {
class PaymentServiceImp implements PaymentService { class PaymentServiceImp implements PaymentService {
MyInAppBrowser? myInAppBrowser; MyInAppBrowser? myInAppBrowser;
// var inAppBrowserOptions = InAppBrowserClassOptions(
// inAppWebViewGroupOptions:
// InAppWebViewGroupOptions(crossPlatform: InAppWebViewOptions(useShouldOverrideUrlLoading: true, transparentBackground: false), ios: IOSInAppWebViewOptions(applePayAPIEnabled: true)),
// crossPlatform: InAppBrowserOptions(hideUrlBar: true, toolbarTopBackgroundColor: Colors.black),
// android: AndroidInAppBrowserOptions(),
// ios:
// IOSInAppBrowserOptions(hideToolbarBottom: true, toolbarBottomBackgroundColor: Colors.white, closeButtonColor: Colors.white, presentationStyle: IOSUIModalPresentationStyle.OVER_FULL_SCREEN));
var inAppBrowserOptions = InAppBrowserClassSettings( var inAppBrowserOptions = InAppBrowserClassSettings(
webViewSettings: InAppWebViewSettings( webViewSettings: InAppWebViewSettings(
useShouldOverrideUrlLoading: false, useShouldOverrideUrlLoading: false,
transparentBackground: false, transparentBackground: false,
@ -113,10 +105,13 @@ class PaymentServiceImp implements PaymentService {
onBrowserLoadStart(onFailure: onFailure, onSuccess: onSuccess, url: url); onBrowserLoadStart(onFailure: onFailure, onSuccess: onSuccess, url: url);
}); });
await myInAppBrowser!.openUrlRequest( await myInAppBrowser!.openUrlRequest(
// Uri.parse(urlRequest) urlRequest: URLRequest(
urlRequest: URLRequest(url: WebUri(urlRequest)), url: WebUri(urlRequest, forceToStringRawValue: true),
allowsCellularAccess: true,
allowsConstrainedNetworkAccess: true,
allowsExpensiveNetworkAccess: true,
),
settings: inAppBrowserOptions, settings: inAppBrowserOptions,
// in: inAppBrowserOptions,
); );
} }

@ -213,9 +213,9 @@ enum ChatTypeEnum {
} }
enum SubscriptionTypeEnum { enum SubscriptionTypeEnum {
current, current, //1
upgrade, upgrade, //2
downgrade, downgrade, //3
} }
enum SubscriptionActionTypeEnum { enum SubscriptionActionTypeEnum {

@ -81,7 +81,8 @@ class LocationService implements Location {
if (granted) { if (granted) {
Geolocator.getLastKnownPosition(forceAndroidLocationManager: true).then((value) { Geolocator.getLastKnownPosition(forceAndroidLocationManager: true).then((value) {
if (value == null) { if (value == null) {
Geolocator.getCurrentPosition().then((value) { Geolocator.getCurrentPosition().then((value) async {
if(value == null) await Geolocator.openAppSettings();
done(value); done(value);
}); });
} else { } else {

@ -1261,7 +1261,14 @@ class AdVM extends BaseVM {
for (var element in images) { for (var element in images) {
imageModels.add(ImageModel(filePath: element.path, isFromNetwork: false)); imageModels.add(ImageModel(filePath: element.path, isFromNetwork: false));
} }
pickedPostingImages.addAll(imageModels); pickedPostingImages.addAll(imageModels);
// Added By Aamir
if (pickedPostingImages.length > GlobalConsts().maxFileCount) {
pickedPostingImages = pickedPostingImages.sublist(0, GlobalConsts().maxFileCount);
Utils.showToast(LocaleKeys.maxFileSelection);
}
if (pickedPostingImages.isNotEmpty) vehicleImageError = ""; if (pickedPostingImages.isNotEmpty) vehicleImageError = "";
notifyListeners(); notifyListeners();
} }
@ -1304,7 +1311,13 @@ class AdVM extends BaseVM {
vehicleDamageCards[index].partImages = imageModels; vehicleDamageCards[index].partImages = imageModels;
} else { } else {
vehicleDamageCards[index].partImages!.addAll(imageModels); vehicleDamageCards[index].partImages!.addAll(imageModels);
// Added By Aamir
if (vehicleDamageCards[index].partImages!.length > GlobalConsts().maxFileCount) {
vehicleDamageCards[index].partImages = vehicleDamageCards[index].partImages!.sublist(0, GlobalConsts().maxFileCount);
Utils.showToast(LocaleKeys.maxFileSelection);
}
} }
vehicleDamageCards[index].partImageErrorValue = ""; vehicleDamageCards[index].partImageErrorValue = "";
notifyListeners(); notifyListeners();
} }
@ -1354,6 +1367,11 @@ class AdVM extends BaseVM {
void pickMultipleDamageImages() async { void pickMultipleDamageImages() async {
List<File> images = await commonServices.pickMultipleImages(); List<File> images = await commonServices.pickMultipleImages();
pickedDamageImages.addAll(images); pickedDamageImages.addAll(images);
if (pickedDamageImages.length > GlobalConsts().maxFileCount) {
pickedDamageImages = pickedDamageImages.sublist(0, GlobalConsts().maxFileCount);
Utils.showToast(LocaleKeys.maxFileSelection);
}
if (pickedDamageImages.isNotEmpty) vehicleDamageImageError = ""; if (pickedDamageImages.isNotEmpty) vehicleDamageImageError = "";
notifyListeners(); notifyListeners();
} }

@ -443,6 +443,11 @@ class ChatVM extends BaseVM {
imageModels.add(ImageModel(filePath: element.path, isFromNetwork: false)); imageModels.add(ImageModel(filePath: element.path, isFromNetwork: false));
} }
pickedImagesForMessage.addAll(imageModels); pickedImagesForMessage.addAll(imageModels);
if (pickedImagesForMessage.length > GlobalConsts().maxFileCount) {
pickedImagesForMessage = pickedImagesForMessage.sublist(0, GlobalConsts().maxFileCount);
Utils.showToast(LocaleKeys.maxFileSelection);
}
notifyListeners(); notifyListeners();
} }

@ -269,10 +269,17 @@ class RequestsVM extends BaseVM {
imageModels.add(ImageModel(filePath: element.path, isFromNetwork: false)); imageModels.add(ImageModel(filePath: element.path, isFromNetwork: false));
} }
pickedVehicleImages.addAll(imageModels); pickedVehicleImages.addAll(imageModels);
if (pickedVehicleImages.length > GlobalConsts().maxFileCount) {
pickedVehicleImages = pickedVehicleImages.sublist(0, GlobalConsts().maxFileCount);
Utils.showToast(LocaleKeys.maxFileSelection);
}
if (pickedVehicleImages.isNotEmpty) vehicleImageError = ""; if (pickedVehicleImages.isNotEmpty) vehicleImageError = "";
notifyListeners(); notifyListeners();
} }
bool isFetchingRequestType = false; bool isFetchingRequestType = false;
bool isFetchingVehicleType = true; bool isFetchingVehicleType = true;
bool isFetchingVehicleDetail = false; bool isFetchingVehicleDetail = false;

@ -140,6 +140,10 @@ class ServiceVM extends BaseVM {
imageModels.add(ImageModel(filePath: element.path, isFromNetwork: false)); imageModels.add(ImageModel(filePath: element.path, isFromNetwork: false));
} }
pickedBranchImages.addAll(imageModels); pickedBranchImages.addAll(imageModels);
if (pickedBranchImages.length > GlobalConsts().maxFileCount) {
pickedBranchImages = pickedBranchImages.sublist(0, GlobalConsts().maxFileCount);
Utils.showToast(LocaleKeys.maxFileSelection);
}
if (pickedBranchImages.isNotEmpty) branchImageError = ""; if (pickedBranchImages.isNotEmpty) branchImageError = "";
notifyListeners(); notifyListeners();
} }
@ -164,7 +168,6 @@ class ServiceVM extends BaseVM {
final BranchDetailModel currentBranch = branches!.data!.serviceProviderBranch!.firstWhere((element) => element.id == selectedBranchId); final BranchDetailModel currentBranch = branches!.data!.serviceProviderBranch!.firstWhere((element) => element.id == selectedBranchId);
for (var element in currentBranch.branchServices!) { for (var element in currentBranch.branchServices!) {
// TODO: Here , we need to add the category deactivated status.
categories.add( categories.add(
CategoryData( CategoryData(
id: element.categoryId, id: element.categoryId,
@ -283,11 +286,11 @@ class ServiceVM extends BaseVM {
isFromNetwork: false, isFromNetwork: false,
)); ));
} }
documentID == 1 // documentID == 1
? commerceCertificates.addAll(imageModels) // ? commerceCertificates.addAll(imageModels)
: documentID == 2 // : documentID == 2
? commercialCertificates.addAll(imageModels) // ? commercialCertificates.addAll(imageModels)
: vatCertificates.addAll(imageModels); // : vatCertificates.addAll(imageModels);
document!.data![index].document = Utils.convertFileToBase64(files.first); document!.data![index].document = Utils.convertFileToBase64(files.first);
document!.data![index].fileExt = Utils.checkFileExt(files.first.path); document!.data![index].fileExt = Utils.checkFileExt(files.first.path);
document!.data![index].documentUrl = files.first.path; document!.data![index].documentUrl = files.first.path;

@ -1,3 +1,4 @@
import 'dart:convert';
import 'dart:developer'; import 'dart:developer';
import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/classes/app_state.dart';
@ -189,7 +190,9 @@ class SubscriptionsVM extends BaseVM {
mySubscriptionsBySp.clear(); mySubscriptionsBySp.clear();
setState(ViewState.busy); setState(ViewState.busy);
// allSubscriptions.data // allSubscriptions.data
print("====================== SUB =============");
for (var element in allSubscriptions.data!) { for (var element in allSubscriptions.data!) {
print("SuBBB "+ element.subscriptionType.toString());
if (element.subscriptionTypeEnum == SubscriptionTypeEnum.current) { if (element.subscriptionTypeEnum == SubscriptionTypeEnum.current) {
mySubscriptionsBySp.add(element); mySubscriptionsBySp.add(element);
} }

@ -18,12 +18,14 @@ import 'package:mc_common_app/models/subscriptions_models/subscription_model.dar
import 'package:mc_common_app/models/user_models/basic_otp.dart'; import 'package:mc_common_app/models/user_models/basic_otp.dart';
import 'package:mc_common_app/models/user_models/change_email.dart'; import 'package:mc_common_app/models/user_models/change_email.dart';
import 'package:mc_common_app/models/user_models/change_mobile.dart'; import 'package:mc_common_app/models/user_models/change_mobile.dart';
import 'package:mc_common_app/models/user_models/cities.dart';
import 'package:mc_common_app/models/user_models/confirm_email.dart'; import 'package:mc_common_app/models/user_models/confirm_email.dart';
import 'package:mc_common_app/models/user_models/confirm_mobile.dart'; import 'package:mc_common_app/models/user_models/confirm_mobile.dart';
import 'package:mc_common_app/models/user_models/confirm_password.dart'; 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/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_compare.dart';
import 'package:mc_common_app/models/user_models/forget_password_otp_request.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/login_password.dart';
import 'package:mc_common_app/models/user_models/register_user.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/user.dart';
@ -43,6 +45,7 @@ import 'package:mc_common_app/views/location_views/map_selection_widget.dart';
import 'package:mc_common_app/widgets/dialog/dialogs.dart'; import 'package:mc_common_app/widgets/dialog/dialogs.dart';
import 'package:mc_common_app/widgets/dialog/message_dialog.dart'; import 'package:mc_common_app/widgets/dialog/message_dialog.dart';
import 'package:mc_common_app/widgets/dialog/otp_dialog.dart'; import 'package:mc_common_app/widgets/dialog/otp_dialog.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
import 'package:mc_common_app/widgets/tab/login_email_tab.dart'; import 'package:mc_common_app/widgets/tab/login_email_tab.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -62,6 +65,9 @@ class UserVM extends BaseVM {
_loginOtherAccount = value; _loginOtherAccount = value;
} }
Country? userCountries;
Cities? userCities;
void updateCompleteProfilePageCheckbox(bool newValue) { void updateCompleteProfilePageCheckbox(bool newValue) {
completeProfilePageCheckbox = newValue; completeProfilePageCheckbox = newValue;
notifyListeners(); notifyListeners();
@ -164,8 +170,35 @@ class UserVM extends BaseVM {
} }
} }
Future<void> performCompleteProfile( Future<void> userDetailsUpdate(BuildContext context, String firstName, String lastName, String? city, String? cityName, String? countryName) async {
BuildContext context, { Utils.showLoading(context);
Map<String, dynamic> res = await userRepo.updateUserInfo(firstName, lastName, city);
Utils.hideLoading(context);
if (res["data"] != null && res["data"].isNotEmpty) {
print(res["data"]);
User localUser = AppState().getUser;
if (localUser.data != null) {
localUser.data!.userInfo!.firstName = res["data"]["firstName"];
localUser.data!.userInfo!.lastName = res["data"]["lastName"];
localUser.data!.userInfo!.cityId = res["data"]["cityID"];
localUser.data!.userInfo!.countryId = res["data"]["countryID"];
if (cityName != null && countryName != null) {
localUser.data!.userInfo!.cityName = cityName;
localUser.data!.userInfo!.countryName = countryName;
}
// localUser.data!.userInfo!.cityId = res["data"]["cityId"];
AppState().setUser = localUser;
}
Utils.showToast(LocaleKeys.userDetailsUpdated.tr());
pop(context);
} else {
Utils.showToast(res.toString() ?? "");
}
notifyListeners();
}
Future<void> performCompleteProfile(BuildContext context, {
required String password, required String password,
required String confirmPassword, required String confirmPassword,
required String firstName, required String firstName,
@ -173,18 +206,21 @@ class UserVM extends BaseVM {
required String email, required String email,
required String? userId, required String? userId,
bool isNeedToPassToken = false, bool isNeedToPassToken = false,
required String cityID,
required String genderID,
}) async { }) async {
if (Utils.passwordValidateStructure(password)) { if (Utils.passwordValidateStructure(password)) {
if (password == confirmPassword) { if (password == confirmPassword) {
Utils.showLoading(context); Utils.showLoading(context);
RegisterUserRespModel user = await userRepo.basicComplete( RegisterUserRespModel user = await userRepo.basicComplete(
userId ?? "", userId ?? "",
firstName, firstName,
lastName, lastName,
email, email,
password, password,
isNeedToPassToken: isNeedToPassToken, cityID,
); genderID,
isNeedToPassToken: isNeedToPassToken);
Utils.hideLoading(context); Utils.hideLoading(context);
if (user.messageStatus == 1) { if (user.messageStatus == 1) {
Utils.showToast(LocaleKeys.successfullyRegistered.tr()); Utils.showToast(LocaleKeys.successfullyRegistered.tr());
@ -207,6 +243,8 @@ class UserVM extends BaseVM {
required String? firstName, required String? firstName,
required String? lastName, required String? lastName,
required String? email, required String? email,
required DropValue? city,
required DropValue? gender,
}) { }) {
bool isValid = true; bool isValid = true;
if (firstName!.isEmpty) { if (firstName!.isEmpty) {
@ -230,6 +268,12 @@ class UserVM extends BaseVM {
Utils.showToast(LocaleKeys.pleaseAcceptTerms.tr()); Utils.showToast(LocaleKeys.pleaseAcceptTerms.tr());
//("Please accept terms"); //("Please accept terms");
isValid = false; isValid = false;
} else if (city == null) {
Utils.showToast(LocaleKeys.cityNameMandatory.tr());
isValid = false;
} else if (gender == null) {
Utils.showToast(LocaleKeys.genderMandatory.tr());
isValid = false;
} }
return isValid; return isValid;
} }
@ -538,8 +582,8 @@ class UserVM extends BaseVM {
type == ClassType.NUMBER && countryCode != null type == ClassType.NUMBER && countryCode != null
? countryCode + phoneNum ? countryCode + phoneNum
: type == ClassType.NUMBER && countryCode == null : type == ClassType.NUMBER && countryCode == null
? phoneNum ? phoneNum
: phoneNum, : phoneNum,
password); password);
Utils.hideLoading(context); Utils.hideLoading(context);
LoginPasswordRespModel user = LoginPasswordRespModel.fromJson(jsonDecode(response.body)); LoginPasswordRespModel user = LoginPasswordRespModel.fromJson(jsonDecode(response.body));
@ -547,8 +591,8 @@ class UserVM extends BaseVM {
SharedPrefManager.setPhoneOrEmail(type == ClassType.NUMBER && countryCode != null SharedPrefManager.setPhoneOrEmail(type == ClassType.NUMBER && countryCode != null
? countryCode + phoneNum ? countryCode + phoneNum
: type == ClassType.NUMBER && countryCode == null : type == ClassType.NUMBER && countryCode == null
? phoneNum ? phoneNum
: phoneNum); : phoneNum);
SharedPrefManager.setUserPassword(password); SharedPrefManager.setUserPassword(password);
navigateReplaceWithName(context, AppRoutes.loginMethodSelection, arguments: user.data!.userToken); navigateReplaceWithName(context, AppRoutes.loginMethodSelection, arguments: user.data!.userToken);
} else { } else {
@ -560,6 +604,18 @@ class UserVM extends BaseVM {
return await userRepo.getAllCountries(); return await userRepo.getAllCountries();
} }
Future<void> getAllCountriesForUser() async {
userCountries = null;
userCities = null;
userCountries = await userRepo.getAllCountries();
notifyListeners();
}
Future<void> getAllCitiesForUser(int countryId) async {
userCities = await userRepo.getAllCites(countryId.toString());
notifyListeners();
}
Future<void> performBasicOtpRegisterPage(BuildContext context, Future<void> performBasicOtpRegisterPage(BuildContext context,
{required String countryCode, required String phoneNum, required int role, bool isNeedToPassToken = false, VoidCallback? reloadPage}) async { {required String countryCode, required String phoneNum, required int role, bool isNeedToPassToken = false, VoidCallback? reloadPage}) async {
Utils.showLoading(context); Utils.showLoading(context);
@ -627,9 +683,9 @@ class UserVM extends BaseVM {
Future<void> updateUserImage(BuildContext context) async { Future<void> updateUserImage(BuildContext context) async {
File? myPick = await commanServices.pickFile(context, fileType: FileType.image); File? myPick = await commanServices.pickFile(context, fileType: FileType.image);
if (myPick != null) { if (myPick != null) {
userRepo.updateUserImage(encodeBase64Image(myPick)).whenComplete(() { await userRepo.updateUserImage(encodeBase64Image(myPick));
AppState().getUser.data!.userInfo!.userLocalImage = myPick; AppState().getUser.data!.userInfo!.userLocalImage = myPick;
}); notifyListeners();
} }
notifyListeners(); notifyListeners();
} }
@ -662,8 +718,13 @@ class UserVM extends BaseVM {
} }
void changeLanguage(BuildContext context) { void changeLanguage(BuildContext context) {
print("${EasyLocalization.of(context)?.currentLocale}"); print("${EasyLocalization
if (EasyLocalization.of(context)?.currentLocale?.countryCode == "SA") { .of(context)
?.currentLocale}");
if (EasyLocalization
.of(context)
?.currentLocale
?.countryCode == "SA") {
context.setLocale(const Locale("en", "US")); context.setLocale(const Locale("en", "US"));
} else { } else {
context.setLocale(const Locale('ar', 'SA')); context.setLocale(const Locale('ar', 'SA'));
@ -688,8 +749,13 @@ class UserVM extends BaseVM {
AppState().setUser = null; AppState().setUser = null;
if (AppState().currentAppType == AppType.provider) { if (AppState().currentAppType == AppType.provider) {
AppState().setproviderSubscription = null; AppState().setproviderSubscription = null;
context.read<SubscriptionsVM>().mySubscriptionsBySp.clear(); context
context.read<SubscriptionsVM>().allSubscriptions = SubscriptionModel(); .read<SubscriptionsVM>()
.mySubscriptionsBySp
.clear();
context
.read<SubscriptionsVM>()
.allSubscriptions = SubscriptionModel();
} }
navigateReplaceWithNameUntilRoute(context, AppRoutes.registerSelection); navigateReplaceWithNameUntilRoute(context, AppRoutes.registerSelection);

@ -54,8 +54,12 @@ class _ProfileScreenState extends State<ProfileScreen> {
if (mySubscription!.id == 1) { if (mySubscription!.id == 1) {
freeTrialName = mySubscription!.name ?? ""; freeTrialName = mySubscription!.name ?? "";
} else { } else {
startDate = (mySubscription!.dateStart != null && mySubscription!.dateStart!.isNotEmpty) ? DateHelper.formatAsDayMonthYear(DateHelper.parseStringToDate(DateHelper.formatDateT(mySubscription!.dateStart!))) : ""; startDate = (mySubscription!.dateStart != null && mySubscription!.dateStart!.isNotEmpty)
endDate = (mySubscription!.dateEnd != null && mySubscription!.dateEnd!.isNotEmpty) ? DateHelper.formatAsDayMonthYear(DateHelper.parseStringToDate(DateHelper.formatDateT(mySubscription!.dateEnd!))) : ""; ? DateHelper.formatAsDayMonthYear(DateHelper.parseStringToDate(DateHelper.formatDateT(mySubscription!.dateStart!)))
: "";
endDate = (mySubscription!.dateEnd != null && mySubscription!.dateEnd!.isNotEmpty)
? DateHelper.formatAsDayMonthYear(DateHelper.parseStringToDate(DateHelper.formatDateT(mySubscription!.dateEnd!)))
: "";
} }
} }
return Stack( return Stack(
@ -101,24 +105,39 @@ class _ProfileScreenState extends State<ProfileScreen> {
child: ListView( child: ListView(
children: [ children: [
60.height, 60.height,
"${AppState().getUser.data!.userInfo!.firstName} ${AppState().getUser.data!.userInfo!.lastName ?? ""}".toText(fontSize: 20).paddingOnly(left: 25), Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [
"${AppState().getUser.data!.userInfo!.firstName} ${AppState().getUser.data!.userInfo!.lastName ?? ""}".toText(fontSize: 20).paddingOnly(left: 25, right: 10),
MyAssets.icEdit.buildSvg(width: 15).onPress(
() async {
Navigator.pushNamed(context, AppRoutes.updateUserDetails);
},
),
],
).margin(left: 0, top: 0, right: 24, bottom: 0),
Column( Column(
children: [ children: [
if (AppState().currentAppType == AppType.provider && mySubscription != null) ...[ if (AppState().currentAppType == AppType.provider && mySubscription != null) ...[
CustomProfileOptionsTile( CustomProfileOptionsTile(
titleText: LocaleKeys.mySubscription.tr(), titleText: LocaleKeys.mySubscription.tr(),
subtitleText: freeTrialName.isNotEmpty ? freeTrialName : "${startDate.isNotEmpty ? "${LocaleKeys.startDate.tr()}: $startDate" : ""} ${endDate.isNotEmpty ? "${LocaleKeys.expiresOn.tr()}: $endDate" : ""}", subtitleText: freeTrialName.isNotEmpty
? freeTrialName
: "${startDate.isNotEmpty ? "${LocaleKeys.startDate.tr()}: $startDate" : ""} ${endDate.isNotEmpty ? "${LocaleKeys.expiresOn.tr()}: $endDate" : ""}",
needBorderBelow: true, needBorderBelow: true,
needEditButton: false, needEditButton: false,
onTap: () {}, onTap: () {},
), ),
], ],
CustomProfileOptionsTile( CustomProfileOptionsTile(
titleText: LocaleKeys.country.tr(), titleText: LocaleKeys.city.tr(),
subtitleText: "Saudi Arabia", subtitleText: "${AppState().getUser.data!.userInfo!.cityName ?? ""}, ${AppState().getUser.data!.userInfo!.countryName ?? ""}",
needBorderBelow: true, needBorderBelow: true,
needEditButton: false, needEditButton: true,
onTap: () {}, onTap: () {
Navigator.pushNamed(context, AppRoutes.updateUserCity);
},
), ),
CustomProfileOptionsTile( CustomProfileOptionsTile(
titleText: LocaleKeys.email.tr(), titleText: LocaleKeys.email.tr(),
@ -194,10 +213,12 @@ class _ProfileScreenState extends State<ProfileScreen> {
width: 40, width: 40,
padding: const EdgeInsets.all(8), padding: const EdgeInsets.all(8),
decoration: BoxDecoration(color: MyColors.white, shape: BoxShape.circle, border: Border.all(color: MyColors.darkTextColor, width: 0.1)), decoration: BoxDecoration(color: MyColors.white, shape: BoxShape.circle, border: Border.all(color: MyColors.darkTextColor, width: 0.1)),
child: MyAssets.icEdit.buildSvg(), child: Center(
child: MyAssets.icEdit.buildSvg(),
),
).onPress( ).onPress(
() async { () async {
await model.updateUserImage(context).whenComplete(() => setState(() {})); await model.updateUserImage(context);
}, },
), ),
), ),

@ -19,6 +19,7 @@ import 'package:mc_common_app/views/advertisement/ad_creation_steps/ad_creation_
import 'package:mc_common_app/views/advertisement/components/picked_images_container_widget.dart'; import 'package:mc_common_app/views/advertisement/components/picked_images_container_widget.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart'; import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart'; import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/common_widgets/search_entity_widget.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:mc_common_app/widgets/txt_field.dart'; import 'package:mc_common_app/widgets/txt_field.dart';
@ -35,6 +36,7 @@ class _ProviderLicensePageState extends State<ProviderLicensePage> {
late ServiceVM branchVM; late ServiceVM branchVM;
bool showAttachment = false; bool showAttachment = false;
String? attachedFile; String? attachedFile;
String? formattedDate;
@override @override
void initState() { void initState() {
@ -50,7 +52,7 @@ class _ProviderLicensePageState extends State<ProviderLicensePage> {
if (model.document != null && model.document!.data != null && model.document!.data!.isNotEmpty) { if (model.document != null && model.document!.data != null && model.document!.data!.isNotEmpty) {
for (var doc in model.document!.data!) { for (var doc in model.document!.data!) {
log("doc: ${doc.status}"); log("doc: ${doc.status}");
if (doc.status == 4 || doc.status == 0) { if (doc.status == DocumentStatusEnum.rejected || doc.status == DocumentStatusEnum.needUpload || doc.isAllowUpdate!) {
isShow = true; isShow = true;
} }
} }
@ -162,6 +164,7 @@ class _ProviderLicensePageState extends State<ProviderLicensePage> {
padding: const EdgeInsets.symmetric(horizontal: 20), padding: const EdgeInsets.symmetric(horizontal: 20),
itemBuilder: (context, index) { itemBuilder: (context, index) {
DocumentData? document = serviceVM.document?.data![index]; DocumentData? document = serviceVM.document?.data![index];
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -172,40 +175,58 @@ class _ProviderLicensePageState extends State<ProviderLicensePage> {
(document!.documentName!).toText(fontSize: 16, letterSpacing: -0.56, fontWeight: MyFonts.SemiBold), (document!.documentName!).toText(fontSize: 16, letterSpacing: -0.56, fontWeight: MyFonts.SemiBold),
if (document.statusText != null && document.statusText!.isNotEmpty) ...[ if (document.statusText != null && document.statusText!.isNotEmpty) ...[
10.width, 10.width,
Utils.statusContainerChip(text: document.statusText!.replaceFirst('OrActive', ''), chipColor: getColorByStatus(document.status ?? 1)), Utils.statusContainerChip(text: document.statusText!.replaceFirst('OrActive', ''), chipColor: getColorByStatus(document.status!)),
], ],
], ],
), ),
// if (document.status != 1 && document.status != 3) ...[ if (document.documentUrl != null) ...[
// Padding( BuildFilesContainer(
// padding: const EdgeInsets.only(top: 4, bottom: 8), image: ImageModel(id: index, filePath: document.documentUrl!, isFromNetwork: document.isLocalFile! ? false : true),
// child: LocaleKeys.enter_licence_detail.tr().toText(fontSize: 14, color: MyColors.lightTextColor), onCrossPressedPrimary: (String val) {
// ), document.documentUrl = null;
// TxtField( document.isLocalFile = false;
// hint: LocaleKeys.description.tr(), setState(() {});
// maxLines: 3, },
// isBackgroundEnabled: true, index: index,
// ), isReview: isReview(document),
// ],
10.height,
if (isNeedToShow(model: serviceVM, document: document)) ...[
PickedFilesContainer(
isReview: document.status != 0 && (document.status == 1 || document.status == 3),
allowAdButton: false,
pickedFiles: isLocalOrNetworkFiles(model: serviceVM, document: document),
onCrossPressedPrimary: isNetworkImage(document: document)
? serviceVM.removeNetworkImage
: document.documentId == 1
? serviceVM.commerceRemove
: document.documentId == 2
? serviceVM.commercialRemove
: serviceVM.vatRemove,
isPdf: true, isPdf: true,
isFromNetwork: !(document.isLocalFile ?? false), ),
onAddFilePressed: () { 5.height,
serviceVM.pickPdfReceiptFile(context, document.documentId!, index); ("${document.documentName} Expiry").toText(fontSize: 14, letterSpacing: -0.56, fontWeight: MyFonts.Medium),
5.height,
TxtField(
isBackgroundEnabled: (document.status == DocumentStatusEnum.pending || document.status == DocumentStatusEnum.approvedOrActive && !document.isAllowUpdate!),
isNeedBorder: document.isAllowUpdate! ? true : false,
isSidePaddingZero: true,
hint: LocaleKeys.expiryDate.tr(),
value: document.dateExpire != null && document.status == DocumentStatusEnum.pending || document.status == DocumentStatusEnum.approvedOrActive ? "${DateFormat('yyyy-MM-dd').format(
DateTime.parse(document.dateExpire!))}" : formattedDate == null
? ""
: "${DateFormat('yyyy-MM-dd').format(DateTime.parse(document.dateExpire!))}",
isNeedClickAll: true,
postFixDataColor: MyColors.darkTextColor,
onTap: () async {
if (document.isAllowUpdate! && document.status == DocumentStatusEnum.approvedOrActive || document.status == DocumentStatusEnum.needUpload ||
document.status == DocumentStatusEnum.rejected) {
formattedDate =
await Utils.pickDateFromDatePicker(context, lastDate: DateTime(DateTime
.now()
.year + 3, DateTime
.now()
.month + 1, DateTime
.now()
.day), firstDate: DateTime.now());
if (formattedDate!.isNotEmpty) {
document.dateExpire = formattedDate;
setState(() {});
}
}
// requestsVM.updateRequestedDate(formattedDate);
}, },
), ),
10.height,
buildCommentContainer(document: document), buildCommentContainer(document: document),
] else ] else
...[ ...[
@ -215,107 +236,133 @@ class _ProviderLicensePageState extends State<ProviderLicensePage> {
text: LocaleKeys.attachPDF.tr(), text: LocaleKeys.attachPDF.tr(),
icon: MyAssets.attachmentIcon.buildSvg(), icon: MyAssets.attachmentIcon.buildSvg(),
), ),
], ]
], ],
); );
}, },
); );
} }
List<ImageModel> isLocalOrNetworkFiles({required ServiceVM model, required DocumentData document}) { bool isReview(DocumentData document) {
bool isNetworkImage = false; print(document.toJson());
bool val = false;
if (!document.isLocalFile!) { if (document.isAllowUpdate == null) {
isNetworkImage = document.documentUrl != null && document.documentUrl!.isNotEmpty ? true : false; val = false;
} }
if (isNetworkImage) { if (document.isAllowUpdate! && document.status == DocumentStatusEnum.approvedOrActive) {
return [ImageModel(id: document.id, isFromNetwork: isNetworkImage, filePath: document.documentUrl)]; val = false;
} else if (document.documentId == 1) {
return model.commerceCertificates;
} else if (document.documentId == 2) {
return model.commercialCertificates;
} else {
return model.vatCertificates;
} }
} if (!document.isAllowUpdate! && document.status == DocumentStatusEnum.approvedOrActive) {
val = true;
bool isNeedToShow({required ServiceVM model, required DocumentData document}) {
bool allow = false;
bool isNetworkImage = document.documentUrl != null && document.documentUrl!.isNotEmpty && !(document.isLocalFile ?? true);
if (isNetworkImage) {
allow = true;
} else {
if (document.documentId == 1 && model.commerceCertificates.isNotEmpty) {
allow = true;
}
if (document.documentId == 2 && model.commercialCertificates.isNotEmpty) {
allow = true;
}
if (document.documentId == 3 && model.vatCertificates.isNotEmpty) {
allow = true;
}
} }
return allow; if (document.isAllowUpdate! && document.status == DocumentStatusEnum.pending) {
} val = true;
dynamic checkOnCrossPress({required ServiceVM model, required DocumentData document}) async {
bool isNetworkImage = document.documentUrl != null && document.documentUrl!.isNotEmpty ? true : false;
if (isNetworkImage) {
return document.documentUrl;
} else {
if (document.documentId == 1) {
model.commerceRemove;
}
if (document.documentId == 2) {
model.commercialRemove;
}
if (document.documentId == 3) {
model.vatRemove;
}
} }
} if (document.isAllowUpdate! && document.status == DocumentStatusEnum.rejected) {
val = false;
bool isNetworkImage({required DocumentData document}) { }
bool isNetworkImage = false; if (document.isAllowUpdate! && document.status == DocumentStatusEnum.needUpload) {
if (!document.isLocalFile!) { val = true;
isNetworkImage = document.documentUrl != null && document.documentUrl!.isNotEmpty ? true : false;
} }
return isNetworkImage; if (document.isAllowUpdate! && document.status == DocumentStatusEnum.review) {
val = true;
}
return val;
} }
Widget buildCommentContainer({required DocumentData document}) { // List<ImageModel> isLocalOrNetworkFiles({required ServiceVM model, required DocumentData document}) {
String comment = ""; // bool isNetworkImage = false;
if (document.status == 4 && document.comment != null) { // print(document);
comment = document.comment ?? ""; // if (!document.isLocalFile!) {
} // isNetworkImage = document.documentUrl != null && document.documentUrl!.isNotEmpty ? true : false;
// }
// if (isNetworkImage) {
// return [ImageModel(id: document.id, isFromNetwork: isNetworkImage, filePath: document.documentUrl)];
// } else {
// return [ImageModel(id: document.id, isFromNetwork: false, filePath: document.documentUrl)];
// ;
// }
// }
if (comment.isEmpty) { // bool isNeedToShow({required ServiceVM model, required DocumentData document}) {
return const SizedBox(); // bool allow = false;
} // bool isNetworkImage = document.documentUrl != null && document.documentUrl!.isNotEmpty && !(document.isLocalFile ?? true);
return Center(child: comment.toString().toText(color: MyColors.adCancelledStatusColor, fontSize: 14)).toContainer( // if (isNetworkImage) {
borderRadius: 8, // allow = true;
margin: const EdgeInsets.only(top: 10), // } else {
width: double.infinity, // if (document.documentId == 1 && document.documentUrl!.isNotEmpty) {
backgroundColor: MyColors.adCancelledStatusColor.withOpacity(0.16), // allow = true;
); // }
// if (document.documentId == 2 && document.documentUrl!.isNotEmpty) {
// allow = true;
// }
// if (document.documentId == 3 && document.documentUrl!.isNotEmpty) {
// allow = true;
// }
// }
// return allow;
// }
//
// dynamic checkOnCrossPress({required ServiceVM model, required DocumentData document}) async {
// bool isNetworkImage = document.documentUrl != null && document.documentUrl!.isNotEmpty ? true : false;
// if (isNetworkImage) {
// print(document.documentUrl);
// return document.documentUrl;
// }
//} else {
// if (document.documentId == 1) {
// model.commerceRemove;
// }
// if (document.documentId == 2) {
// model.commercialRemove;
// }
// if (document.documentId == 3) {
// model.vatRemove;
// }
// }
}
bool isNetworkImage({required DocumentData document}) {
bool isNetworkImage = false;
if (!document.isLocalFile!) {
isNetworkImage = document.documentUrl != null && document.documentUrl!.isNotEmpty ? true : false;
}
return isNetworkImage;
}
Widget buildCommentContainer({required DocumentData document}) {
String comment = "";
if (document.status == 4 && document.comment != null) {
comment = document.comment ?? "";
} }
Color getColorByStatus(int docStatus) { if (comment.isEmpty) {
switch (docStatus) { return const SizedBox();
case 1: }
return MyColors.adPendingStatusColor; return Center(child: comment.toString().toText(color: MyColors.adCancelledStatusColor, fontSize: 14)).toContainer(
borderRadius: 8,
margin: const EdgeInsets.only(top: 10),
width: double.infinity,
backgroundColor: MyColors.adCancelledStatusColor.withOpacity(0.16),
);
}
case 2: Color getColorByStatus(DocumentStatusEnum docStatus) {
return MyColors.adActiveStatusColor; switch (docStatus) {
case DocumentStatusEnum.pending:
return MyColors.adPendingStatusColor;
case 3: case DocumentStatusEnum.approvedOrActive:
return MyColors.greenColor; return MyColors.adActiveStatusColor;
case 4: case DocumentStatusEnum.rejected:
return MyColors.adCancelledStatusColor; return MyColors.adCancelledStatusColor;
default: case DocumentStatusEnum.needUpload:
return MyColors.adPendingStatusColor; return MyColors.adPendingStatusColor;
} default:
return MyColors.adPendingStatusColor;
} }
} }

@ -41,12 +41,12 @@ class _ChangeEmailPageState extends State<ChangeEmailPage> {
padding: const EdgeInsets.all(20), padding: const EdgeInsets.all(20),
child: Column( child: Column(
children: [ children: [
LocaleKeys.enterEmail.tr().toText( // LocaleKeys.enterEmail.tr().toText(
height: 23 / 24, // height: 23 / 24,
fontSize: 24, // fontSize: 24,
letterSpacing: -1.44, // letterSpacing: -1.44,
), // ),
12.height, // 12.height,
TxtField( TxtField(
hint: LocaleKeys.enterNewEmail.tr(), hint: LocaleKeys.enterNewEmail.tr(),
onChanged: (v) => email = v, onChanged: (v) => email = v,

@ -39,12 +39,12 @@ class _ChangeMobilePageState extends State<ChangeMobilePage> {
padding: const EdgeInsets.all(20), padding: const EdgeInsets.all(20),
child: Column( child: Column(
children: [ children: [
LocaleKeys.enterNewPhoneNumber.tr().toText( // LocaleKeys.enterNewPhoneNumber.tr().toText(
height: 23 / 24, // height: 23 / 24,
fontSize: 24, // fontSize: 24,
letterSpacing: -1.44, // letterSpacing: -1.44,
), // ),
12.height, // 12.height,
TxtField( TxtField(
hint: LocaleKeys.enterNewPhoneNumber.tr(), hint: LocaleKeys.enterNewPhoneNumber.tr(),
onChanged: (v) => mobileNo = v, onChanged: (v) => mobileNo = v,

@ -39,12 +39,12 @@ class _ChangePasswordPageState extends State<ChangePasswordPage> {
padding: const EdgeInsets.all(20), padding: const EdgeInsets.all(20),
child: Column( child: Column(
children: [ children: [
LocaleKeys.enterNewPassword.tr().toText( // LocaleKeys.enterNewPassword.tr().toText(
height: 23 / 24, // height: 23 / 24,
fontSize: 24, // fontSize: 24,
letterSpacing: -1.44, // letterSpacing: -1.44,
), // ),
12.height, // 12.height,
TxtField( TxtField(
hint: LocaleKeys.enterOldPassword.tr(), hint: LocaleKeys.enterOldPassword.tr(),
onChanged: (v) => currentPassword = v, onChanged: (v) => currentPassword = v,

@ -1,3 +1,4 @@
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/classes/consts.dart';
import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/config/routes.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
@ -9,6 +10,7 @@ import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/view_models/user_view_model.dart'; import 'package:mc_common_app/view_models/user_view_model.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart'; import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart'; import 'package:mc_common_app/widgets/button/show_fill_button.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/extensions/extensions_widget.dart';
import 'package:mc_common_app/widgets/txt_field.dart'; import 'package:mc_common_app/widgets/txt_field.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
@ -25,182 +27,246 @@ class CompleteProfilePage extends StatefulWidget {
} }
class _CompleteProfilePageState extends State<CompleteProfilePage> { class _CompleteProfilePageState extends State<CompleteProfilePage> {
String? firstName = "", lastName = "", email = "", confirmPassword = ""; String? firstName = "",
lastName = "",
email = "",
confirmPassword = "";
late String password = ""; late String password = "";
bool isChecked = false; bool isChecked = false;
late UserVM userVM; DropValue? city;
DropValue? gender;
@override @override
void initState() { void initState() {
userVM = Provider.of<UserVM>(context, listen: false);
super.initState(); super.initState();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Consumer(builder: (BuildContext context, UserVM userVM, Widget? child) {
appBar: CustomAppBar( print("Country ID = " + AppState().getUserRegisterCountrySelection.id.toString());
isRemoveBackButton: widget.user.data!.roleId == 7 ? false : true, userVM.getAllCitiesForUser(AppState().getUserRegisterCountrySelection.id);
title: widget.user.data!.roleId == 7 ? "" : LocaleKeys.signUp.tr(), return Scaffold(
), appBar: CustomAppBar(
body: SizedBox( isRemoveBackButton: widget.user.data!.roleId == 7 ? false : true,
width: double.infinity, title: widget.user.data!.roleId == 7 ? "" : LocaleKeys.signUp.tr(),
height: double.infinity, ),
child: SingleChildScrollView( body: SizedBox(
child: Padding( width: double.infinity,
padding: const EdgeInsets.all(20), height: double.infinity,
child: Column( child: SingleChildScrollView(
children: [ child: Padding(
6.height, padding: const EdgeInsets.all(20),
LocaleKeys.completeProfile.tr().toText( child: Column(
children: [
6.height,
LocaleKeys.completeProfile.tr().toText(
height: 23 / 24, height: 23 / 24,
fontSize: 24, fontSize: 24,
letterSpacing: -1.44, letterSpacing: -1.44,
), ),
12.height, 12.height,
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 20), padding: const EdgeInsets.symmetric(horizontal: 20),
child: LocaleKeys.profileMsg.tr().toText( child: LocaleKeys.profileMsg.tr().toText(
color: MyColors.lightTextColor, color: MyColors.lightTextColor,
textAlign: TextAlign.center, textAlign: TextAlign.center,
fontSize: 14, fontSize: 14,
height: 23 / 24, height: 23 / 24,
letterSpacing: -0.48, letterSpacing: -0.48,
), ),
), ),
12.height, 12.height,
TxtField( TxtField(
hint: LocaleKeys.firstName.tr(), hint: LocaleKeys.firstName.tr(),
value: firstName, value: firstName,
onChanged: (v) { onChanged: (v) {
firstName = v; firstName = v;
}, },
), ),
12.height, 12.height,
TxtField( TxtField(
hint: LocaleKeys.surname.tr(), hint: LocaleKeys.surname.tr(),
value: lastName, value: lastName,
onChanged: (v) { onChanged: (v) {
lastName = v; lastName = v;
}, },
), ),
12.height, 12.height,
TxtField( Container(
hint: LocaleKeys.email.tr(), padding: const EdgeInsets.only(right: 0, left: 0, top: 0, bottom: 0),
value: email, child: Builder(builder: (context) {
// isButtonEnable: email!.length > 0 ? true : false, List<DropValue> userGender = [];
buttonTitle: LocaleKeys.verify.tr(), userGender.add(DropValue(1.toInt(), "${LocaleKeys.userMale.tr()}", "", isEnabled: true));
onChanged: (v) { userGender.add(DropValue(2.toInt(), "${LocaleKeys.userFemale.tr()}", "", isEnabled: true));
email = v; // for (var element in userVM.userCities!.data!) {
}, // if (AppState().getUser.data != null) {
), // if (AppState().getUser.data!.userInfo!.cityId == element.id) {
12.height, // city = DropValue(element.id?.toInt() ?? 0, element.cityName ?? "", "");
TxtField( // }
hint: LocaleKeys.createPass.tr(), // }
isPasswordEnabled: true, //
maxLines: 1, // }
value: password, return DropdownField(
onChanged: (v) { (DropValue value) {
password = v; gender = value;
}, setState(() {});
), },
12.height, list: userGender,
TxtField( dropdownValue: gender != null && gender != -1 ? DropValue(gender!.id, gender!.value, "") : null,
hint: LocaleKeys.confirmPass.tr(), hint: gender != null && gender != -1 ? gender!.value : "${LocaleKeys.userGender.tr()} *",
isPasswordEnabled: true, // errorValue: adVM.vehicleCountryId.errorValue,
maxLines: 1, );
value: confirmPassword, })),
onChanged: (v) { 12.height,
confirmPassword = v; TxtField(
}, hint: LocaleKeys.email.tr(),
), value: email,
50.height, // isButtonEnable: email!.length > 0 ? true : false,
Row( buttonTitle: LocaleKeys.verify.tr(),
mainAxisAlignment: MainAxisAlignment.start, onChanged: (v) {
crossAxisAlignment: CrossAxisAlignment.center, email = v;
children: [ },
Consumer(builder: (BuildContext context, UserVM userVM, Widget? child) { ),
return Checkbox( 12.height,
value: userVM.completeProfilePageCheckbox, userVM.userCities != null
activeColor: MyColors.darkPrimaryColor, ? Container(
onChanged: (value) { padding: const EdgeInsets.only(right: 0, left: 0, top: 0, bottom: 0),
userVM.updateCompleteProfilePageCheckbox(value!); child: Builder(builder: (context) {
}, List<DropValue> userCityDrop = [];
); for (var element in userVM.userCities!.data!) {
}), if (AppState().getUser.data != null) {
Expanded( if (AppState().getUser.data!.userInfo!.cityId == element.id) {
child: Text.rich( city = DropValue(element.id?.toInt() ?? 0, element.cityName ?? "", "");
TextSpan( }
children: [ }
userCityDrop.add(DropValue(element.id?.toInt() ?? 0, element.cityName ?? "", ""));
}
return DropdownField(
(DropValue value) {
city = value;
setState(() {});
},
list: userCityDrop,
dropdownValue: city != null && city != -1 ? DropValue(city!.id, city!.value, "") : null,
hint: city != null && city != -1 ? city!.value : "${LocaleKeys.city.tr()} *",
// errorValue: adVM.vehicleCountryId.errorValue,
);
}))
: SizedBox(),
12.height,
TxtField(
hint: LocaleKeys.createPass.tr(),
isPasswordEnabled: true,
maxLines: 1,
value: password,
onChanged: (v) {
password = v;
},
),
12.height,
TxtField(
hint: LocaleKeys.confirmPass.tr(),
isPasswordEnabled: true,
maxLines: 1,
value: confirmPassword,
onChanged: (v) {
confirmPassword = v;
},
),
50.height,
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Consumer(builder: (BuildContext context, UserVM userVM, Widget? child) {
return Checkbox(
value: userVM.completeProfilePageCheckbox,
activeColor: MyColors.darkPrimaryColor,
onChanged: (value) {
userVM.updateCompleteProfilePageCheckbox(value!);
},
);
}),
Expanded(
child: Text.rich(
TextSpan( TextSpan(
text: LocaleKeys.termsOfService.tr(), children: [
style: const TextStyle(fontSize: 12, fontWeight: MyFonts.Medium), TextSpan(
text: LocaleKeys.termsOfService.tr(),
style: const TextStyle(fontSize: 12, fontWeight: MyFonts.Medium),
),
TextSpan(
text: " ${LocaleKeys.terms.tr()}",
style: const TextStyle(
decoration: TextDecoration.underline,
fontSize: 12,
color: MyColors.darkPrimaryColor,
fontWeight: MyFonts.Bold,
))
],
), ),
TextSpan( ).onPress(() {
text: " ${LocaleKeys.terms.tr()}", navigateWithName(context, AppRoutes.settingOptionsTermsAndConditions);
style: const TextStyle( }),
decoration: TextDecoration.underline, )
fontSize: 12, // Column(
color: MyColors.darkPrimaryColor, // children: [
fontWeight: MyFonts.Bold, // LocaleKeys.termsOfService.tr().toText(fontSize: 12),
)) // LocaleKeys.terms.tr().toText(fontSize: 12, color: MyColors.darkPrimaryColor),
], // ],
), // ),
).onPress(() { // Theme(
navigateWithName(context, AppRoutes.settingOptionsTermsAndConditions); // data: ThemeData(unselectedWidgetColor: Colors.transparent),
}), // child: Checkbox(
) // value: false,
// Column( // onChanged: (_) {},
// children: [ // ),
// LocaleKeys.termsOfService.tr().toText(fontSize: 12), // )
// LocaleKeys.terms.tr().toText(fontSize: 12, color: MyColors.darkPrimaryColor), ],
// ], ),
// ), 16.height,
// Theme( Consumer(builder: (BuildContext context, UserVM userVM, Widget? child) {
// data: ThemeData(unselectedWidgetColor: Colors.transparent), return ShowFillButton(
// child: Checkbox( title: LocaleKeys.save.tr(),
// value: false, maxWidth: double.infinity,
// onChanged: (_) {}, isDisabled: !userVM.completeProfilePageCheckbox,
// ), onPressed: () {
// ) if (!userVM.completeProfilePageCheckbox) {
return;
}
bool validateStatus = userVM.dataValidation(password: password,
firstName: firstName,
lastName: lastName,
email: email,
city: city,
gender: gender);
if (validateStatus) {
userVM.performCompleteProfile(
context,
password: password,
confirmPassword: confirmPassword!,
firstName: firstName!,
lastName: lastName!,
email: email!,
userId: widget.user.data!.userId ?? "",
isNeedToPassToken: widget.user.data!.isNeedToPassToken,
cityID: city!.id.toString(),
genderID: gender!.id.toString(),
);
}
});
}),
16.height,
], ],
), ),
16.height, ),
Consumer(builder: (BuildContext context, UserVM userVM, Widget? child) {
return ShowFillButton(
title: LocaleKeys.save.tr(),
maxWidth: double.infinity,
isDisabled: !userVM.completeProfilePageCheckbox,
onPressed: () {
if (!userVM.completeProfilePageCheckbox) {
return;
}
bool validateStatus = userVM.dataValidation(
password: password,
firstName: firstName,
lastName: lastName,
email: email,
);
if (validateStatus) {
userVM.performCompleteProfile(
context,
password: password,
confirmPassword: confirmPassword!,
firstName: firstName!,
lastName: lastName!,
email: email!,
userId: widget.user.data!.userId ?? "",
isNeedToPassToken: widget.user.data!.isNeedToPassToken,
);
}
});
}),
16.height,
],
), ),
), ),
), );
), }
); );
} }
} }

@ -1,3 +1,4 @@
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_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/generated/locale_keys.g.dart';
@ -79,7 +80,7 @@ class _RegisterPageState extends State<RegisterCustomerPage> {
dropdownValue: selectedDrop, dropdownValue: selectedDrop,
(DropValue value) { (DropValue value) {
selectedDrop = value; selectedDrop = value;
AppState().setUserRegisterCountrySelection = value;
setState(() { setState(() {
countryCode = value.subValue; countryCode = value.subValue;
countryId = value.id; countryId = value.id;

@ -1,5 +1,6 @@
import 'dart:developer'; import 'dart:developer';
import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/config/dependency_injection.dart'; import 'package:mc_common_app/config/dependency_injection.dart';
import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/int_extensions.dart';
import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart';
@ -118,8 +119,12 @@ class _RegisterPageState extends State<RegisterProviderPage> {
if (snapshot.hasData) { if (snapshot.hasData) {
List<DropValue> dropList = []; List<DropValue> dropList = [];
snapshot.data?.data?.forEach((element) { snapshot.data?.data?.forEach((element) {
dropList.add(DropValue(element.id ?? 0, dropList.add(DropValue(
EasyLocalization.of(context)?.currentLocale?.countryCode == "SA" ? "${element.countryNameN ?? ""} ${element.countryCode ?? ""}" : "${element.countryName ?? ""} ${element.countryCode ?? ""}", element.countryCode ?? "")); element.id ?? 0,
EasyLocalization.of(context)?.currentLocale?.countryCode == "SA"
? "${element.countryNameN ?? ""} ${element.countryCode ?? ""}"
: "${element.countryName ?? ""} ${element.countryCode ?? ""}",
element.countryCode ?? ""));
}); });
return Column( return Column(
children: [ children: [
@ -132,6 +137,7 @@ class _RegisterPageState extends State<RegisterProviderPage> {
DropdownField( DropdownField(
(DropValue value) { (DropValue value) {
selectedDrop = value; selectedDrop = value;
AppState().setUserRegisterCountrySelection = value;
setState(() { setState(() {
countryCode = value.subValue; countryCode = value.subValue;
countryId = value.id; countryId = value.id;

@ -0,0 +1,123 @@
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/widgets_models.dart';
import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/view_models/ad_view_model.dart';
import 'package:mc_common_app/view_models/user_view_model.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart';
import 'package:mc_common_app/widgets/txt_field.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class UpdateUserCityCountry extends StatefulWidget {
const UpdateUserCityCountry({Key? key}) : super(key: key);
@override
State<UpdateUserCityCountry> createState() => _UpdateUserCityCountryState();
}
class _UpdateUserCityCountryState extends State<UpdateUserCityCountry> {
DropValue? city;
DropValue? country;
@override
void initState() {
print(AppState().getUser!.data!.userInfo!.toJson());
context.read<UserVM>().getAllCountriesForUser();
super.initState();
}
@override
void dispose() {
city = null;
country = null;
print(" Dispose Called");
super.dispose();
}
@override
Widget build(BuildContext context) {
return Consumer(builder: (BuildContext context, UserVM uVM, Widget? child) {
return Scaffold(
appBar: CustomAppBar(
title: LocaleKeys.updateCity.tr(),
),
body: Column(
children: [
uVM.userCountries != null
? Container(
padding: const EdgeInsets.only(right: 20, left: 20, top: 12),
child: Builder(builder: (context) {
List<DropValue> userCountryDrop = [];
for (var element in uVM.userCountries!.data!) {
var countryid = country == null ? AppState().getUser.data!.userInfo!.countryId : country!.id;
print("Country ID" + countryid.toString());
if (countryid == element.id) {
print("Country Matched");
country = DropValue(element.id?.toInt() ?? 0, element.countryName ?? "", "");
}
userCountryDrop.add(DropValue(element.id?.toInt() ?? 0, element.countryName ?? "", ""));
}
return DropdownField(
(DropValue value) async {
country = value;
city = null;
await uVM.getAllCitiesForUser(country!.id);
setState(() {});
},
list: userCountryDrop,
dropdownValue: country != null && country != -1 ? DropValue(country!.id, country!.value, "") : null,
hint: country != null && country != -1 ? country!.value : "${LocaleKeys.country.tr()} *",
// errorValue: adVM.vehicleCountryId.errorValue,
);
}))
: SizedBox(),
uVM.userCities != null && uVM.userCities!.data!.isNotEmpty
? Container(
padding: const EdgeInsets.only(right: 20, left: 20, top: 12),
child: Builder(builder: (context) {
List<DropValue> userCityDrop = [];
for (var element in uVM.userCities!.data!) {
var cid = city == null ? AppState().getUser.data!.userInfo!.cityId : city!.id;
print("City ID" + cid.toString());
if (cid == element.id) {
city = DropValue(element.id?.toInt() ?? 0, element.cityName ?? "", "");
}
userCityDrop.add(DropValue(element.id?.toInt() ?? 0, element.cityName ?? "", ""));
}
return DropdownField(
(DropValue value) {
city = value;
setState(() {});
},
list: userCityDrop,
dropdownValue: city != null && city!.id != -1 ? DropValue(city!.id, city!.value, "") : null,
hint: city != null && city != -1 ? city!.value : "${LocaleKeys.city.tr()} *",
// errorValue: uVM.userCities!.data!.isEmpty ? "No Cities Found" : "",
);
}))
: SizedBox(),
20.height,
Padding(
padding: const EdgeInsets.all(20.0),
child: ShowFillButton(
title: LocaleKeys.confirm.tr(),
maxWidth: double.infinity,
onPressed: () async {
await uVM.userDetailsUpdate(
context, AppState().getUser.data!.userInfo!.firstName!, AppState().getUser.data!.userInfo!.lastName!, city != null ? city?.id.toString() : null, city!.value, country!.value);
},
),
),
],
),
);
});
}
}

@ -0,0 +1,68 @@
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/view_models/user_view_model.dart';
import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart';
import 'package:mc_common_app/widgets/txt_field.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class UpdateUserDetails extends StatefulWidget {
const UpdateUserDetails({Key? key}) : super(key: key);
@override
State<UpdateUserDetails> createState() => _UpdateUserDetailsState();
}
class _UpdateUserDetailsState extends State<UpdateUserDetails> {
String firstname = "";
String lastname = "";
late UserVM userVM;
@override
void initState() {
userVM = Provider.of<UserVM>(context, listen: false);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
title: LocaleKeys.updateUserDetails.tr(),
),
body: SingleChildScrollView(
child: Container(
// width: double.infinity,
// height: double.infinity,
padding: const EdgeInsets.all(20),
child: Column(
children: [
TxtField(
hint: LocaleKeys.enterNewFirstName.tr(),
onChanged: (v) => firstname = v,
),
12.height,
TxtField(
hint: LocaleKeys.enterNewLastName.tr(),
onChanged: (v) => lastname = v,
),
40.height,
ShowFillButton(
title: LocaleKeys.confirm.tr(),
maxWidth: double.infinity,
onPressed: () async {
await userVM.userDetailsUpdate(context, firstname, lastname, AppState().getUser.data!.userInfo!.cityId!.toString(), null, null);
},
),
],
),
),
),
);
}
}
Loading…
Cancel
Save