Localization 1.1

localization_aamir
Aamir.Muhammad 2 years ago
parent e699b8f4a6
commit 77d08afd0d

@ -509,7 +509,68 @@
"selectCategory": "اختر الفئة", "selectCategory": "اختر الفئة",
"searchByService": "البحث حسب الخدمة", "searchByService": "البحث حسب الخدمة",
"selectServices": "اختر الخدمات", "selectServices": "اختر الخدمات",
"modifyPackage": "تعديل الحزمة" "modifyPackage": "تعديل الحزمة",
"schedule": "الجدول",
"serviceLocation": "موقع الخدمة:",
"workshop": "ورشة العمل",
"itemsSelected": "العناصر المحددة",
"workshopFullAccessServices": "بعض الخدمات غير متوفرة في الموقع المنزلي. قم بتغيير الموقع إلى ورشة العمل للوصول الكامل إلى الخدمات",
"changeLocationService": "تغيير الموقع أو الخدمة:",
"noItemstoShow": "لا توجد عناصر لعرضها.",
"someDescriptionSubServices": "بعض الوصف عن الخدمات الفرعية",
"selectServicesYouWant": "اختر الخدمات التي تريدها",
"selectServiceType": "اختر نوع الخدمة",
"selectDateAndTime": "اختر التاريخ والوقت",
"reviewAppointment": "مراجعة الموعد",
"carEngineCheck": "فحص محرك السيارة",
"dateAndTime": "التاريخ والوقت",
"timeLocation": "الوقت والموقع",
"serviceCharges": "رسوم الخدمة",
"locationCharges": "رسوم الموقع",
"payableNow": "المبلغ المستحق الآن",
"remainingAmount": "المبلغ المتبقي",
"branchesFilter": "تصفية الفروع",
"searchByDistance": "البحث حسب المسافة",
"searchByMinimumRatings": "البحث حسب التقييمات الأدنى",
"chat": "الدردشة",
"noRequestsShow": "لا توجد طلبات لعرضها.",
"typeMessageHere": "اكتب رسالتك هنا..",
"reject": "رفض",
"newOfferRequired": "مطلوب عرض جديد",
"offerHasBeenAccepted": "تم قبول العرض",
"offerHasBeenRejected": "تم رفض العرض",
"offerHasBeenCancelled": "تم إلغاء العرض",
"paymentMethod": "طريقة الدفع",
"selectPaymentMethod": "اختر طريقة الدفع",
"password": "كلمة المرور",
"customerName": "اسم العميل",
"createRequest": "إنشاء طلب",
"requestType": "نوع الطلب",
"brand": "العلامة التجارية",
"year": "السنة",
"price": "السعر",
"shippingDelivery": "الشحن/التسليم",
"offers": "العروض",
"noOffersShow": "لا توجد عروض لعرضها",
"allDocumentMandatoryDealershipProvider": "جميع المستندات إلزامية لمقدم خدمات الوكالة",
"documentsUploadedSuccessfully": "تم تحميل المستندات بنجاح",
"help": "المساعدة",
"faqs": "الأسئلة الشائعة",
"contactUs": "اتصل بنا",
"termPrivacy": "الشروط والخصوصية",
"inviteFriends": "دعوة الأصدقاء",
"more": "المزيد",
"language": "اللغة",
"mySubscriptions": "اشتراكاتي",
"subscriptions": "الاشتراكات",
"defineLicenses": "تحديد التراخيص",
"logOut": "تسجيل الخروج",
"customer": "العميل",
"accept": "قبول"

@ -510,14 +510,62 @@
"selectCategory":"Select Category", "selectCategory":"Select Category",
"searchByService":"Search By Service", "searchByService":"Search By Service",
"selectServices":"Select Services", "selectServices":"Select Services",
"modifyPackage": "Modify Package" "modifyPackage": "Modify Package",
"schedule": "Schedule",
"serviceLocation": "Service Location:",
"workshop": "Workshop",
"itemsSelected": "Item(s) Selected",
"workshopFullAccessServices": "Few services are not available on home location. Change the location to workshop to full access the services",
"changeLocationService": "Change location or service:",
"noItemstoShow": "No Items to show.",
"someDescriptionSubServices": "Some description about the sub-services",
"selectServicesYouWant": "Select services you want",
"selectServiceType": "Select service type",
"selectDateAndTime": "Select date and time",
"reviewAppointment": "Review Appointment",
"carEngineCheck": "Car Engine Check",
"dateAndTime": "Date and Time",
"timeLocation": "Time & Location",
"serviceCharges": "Service Charges",
"locationCharges" : "Location Charges",
"payableNow": "Payable Now",
"remainingAmount": "Remaining Amount",
"branchesFilter": "Branches Filter",
"searchByDistance": "Search By Distance",
"searchByMinimumRatings": "Search By Minimum Ratings",
"chat": "Chat",
"noRequestsShow": "No Requests to show.",
"typeMessageHere": "Type your message here..",
"reject": "Reject",
"newOfferRequired": "New Offer Required",
"offerHasBeenAccepted": "Offer has been accepted",
"offerHasBeenRejected": "Offer has been rejected",
"offerHasBeenCancelled": "Offer has been cancelled",
"paymentMethod": "Payment Method",
"selectPaymentMethod": "Select Payment Method",
"password": "Password",
"customerName": "Customer Name",
"createRequest": "Create Request",
"requestType": "Request Type",
"brand": "Brand",
"year": "Year",
"price": "Price",
"shippingDelivery": "Shipping/Delivery",
"offers": "Offers",
"noOffersShow": "No Offers to show",
"allDocumentMandatoryDealershipProvider": "All document's are mandatory for Dealership Provider",
"documentsUploadedSuccessfully": "Documents uploaded successfully",
"help": "Help",
"faqs": "FAQs",
"contactUs": "Contact Us",
"termPrivacy": "Term & Privacy",
"inviteFriends": "Invite Friends",
"more": "More",
"language" :"Language",
"mySubscriptions": "My Subscriptions",
"subscriptions": "Subscriptions",
"defineLicenses": "Define Licenses",
"logOut": "Log Out",
"customer": "Customer",
"accept": "Accept"
} }

@ -525,7 +525,64 @@ class CodegenLoader extends AssetLoader{
"selectCategory": "اختر الفئة", "selectCategory": "اختر الفئة",
"searchByService": "البحث حسب الخدمة", "searchByService": "البحث حسب الخدمة",
"selectServices": "اختر الخدمات", "selectServices": "اختر الخدمات",
"modifyPackage": "تعديل الحزمة" "modifyPackage": "تعديل الحزمة",
"schedule": "الجدول",
"serviceLocation": "موقع الخدمة:",
"workshop": "ورشة العمل",
"itemsSelected": "العناصر المحددة",
"workshopFullAccessServices": "بعض الخدمات غير متوفرة في الموقع المنزلي. قم بتغيير الموقع إلى ورشة العمل للوصول الكامل إلى الخدمات",
"changeLocationService": "تغيير الموقع أو الخدمة:",
"noItemstoShow": "لا توجد عناصر لعرضها.",
"someDescriptionSubServices": "بعض الوصف عن الخدمات الفرعية",
"selectServicesYouWant": "اختر الخدمات التي تريدها",
"selectServiceType": "اختر نوع الخدمة",
"selectDateAndTime": "اختر التاريخ والوقت",
"reviewAppointment": "مراجعة الموعد",
"carEngineCheck": "فحص محرك السيارة",
"dateAndTime": "التاريخ والوقت",
"timeLocation": "الوقت والموقع",
"serviceCharges": "رسوم الخدمة",
"locationCharges": "رسوم الموقع",
"payableNow": "المبلغ المستحق الآن",
"remainingAmount": "المبلغ المتبقي",
"branchesFilter": "تصفية الفروع",
"searchByDistance": "البحث حسب المسافة",
"searchByMinimumRatings": "البحث حسب التقييمات الأدنى",
"chat": "الدردشة",
"noRequestsShow": "لا توجد طلبات لعرضها.",
"typeMessageHere": "اكتب رسالتك هنا..",
"reject": "رفض",
"newOfferRequired": "مطلوب عرض جديد",
"offerHasBeenAccepted": "تم قبول العرض",
"offerHasBeenRejected": "تم رفض العرض",
"offerHasBeenCancelled": "تم إلغاء العرض",
"paymentMethod": "طريقة الدفع",
"selectPaymentMethod": "اختر طريقة الدفع",
"password": "كلمة المرور",
"customerName": "اسم العميل",
"createRequest": "إنشاء طلب",
"requestType": "نوع الطلب",
"brand": "العلامة التجارية",
"year": "السنة",
"price": "السعر",
"shippingDelivery": "الشحن/التسليم",
"offers": "العروض",
"noOffersShow": "لا توجد عروض لعرضها",
"allDocumentMandatoryDealershipProvider": "جميع المستندات إلزامية لمقدم خدمات الوكالة",
"documentsUploadedSuccessfully": "تم تحميل المستندات بنجاح",
"help": "المساعدة",
"faqs": "الأسئلة الشائعة",
"contactUs": "اتصل بنا",
"termPrivacy": "الشروط والخصوصية",
"inviteFriends": "دعوة الأصدقاء",
"more": "المزيد",
"language": "اللغة",
"mySubscriptions": "اشتراكاتي",
"subscriptions": "الاشتراكات",
"defineLicenses": "تحديد التراخيص",
"logOut": "تسجيل الخروج",
"customer": "العميل",
"accept": "قبول"
}; };
static const Map<String,dynamic> en_US = { static const Map<String,dynamic> en_US = {
"firstTimeLogIn": "First Time Log In", "firstTimeLogIn": "First Time Log In",
@ -1039,7 +1096,64 @@ static const Map<String,dynamic> en_US = {
"selectCategory": "Select Category", "selectCategory": "Select Category",
"searchByService": "Search By Service", "searchByService": "Search By Service",
"selectServices": "Select Services", "selectServices": "Select Services",
"modifyPackage": "Modify Package" "modifyPackage": "Modify Package",
"schedule": "Schedule",
"serviceLocation": "Service Location:",
"workshop": "Workshop",
"itemsSelected": "Item(s) Selected",
"workshopFullAccessServices": "Few services are not available on home location. Change the location to workshop to full access the services",
"changeLocationService": "Change location or service:",
"noItemstoShow": "No Items to show.",
"someDescriptionSubServices": "Some description about the sub-services",
"selectServicesYouWant": "Select services you want",
"selectServiceType": "Select service type",
"selectDateAndTime": "Select date and time",
"reviewAppointment": "Review Appointment",
"carEngineCheck": "Car Engine Check",
"dateAndTime": "Date and Time",
"timeLocation": "Time & Location",
"serviceCharges": "Service Charges",
"locationCharges": "Location Charges",
"payableNow": "Payable Now",
"remainingAmount": "Remaining Amount",
"branchesFilter": "Branches Filter",
"searchByDistance": "Search By Distance",
"searchByMinimumRatings": "Search By Minimum Ratings",
"chat": "Chat",
"noRequestsShow": "No Requests to show.",
"typeMessageHere": "Type your message here..",
"reject": "Reject",
"newOfferRequired": "New Offer Required",
"offerHasBeenAccepted": "Offer has been accepted",
"offerHasBeenRejected": "Offer has been rejected",
"offerHasBeenCancelled": "Offer has been cancelled",
"paymentMethod": "Payment Method",
"selectPaymentMethod": "Select Payment Method",
"password": "Password",
"customerName": "Customer Name",
"createRequest": "Create Request",
"requestType": "Request Type",
"brand": "Brand",
"year": "Year",
"price": "Price",
"shippingDelivery": "Shipping/Delivery",
"offers": "Offers",
"noOffersShow": "No Offers to show",
"allDocumentMandatoryDealershipProvider": "All document's are mandatory for Dealership Provider",
"documentsUploadedSuccessfully": "Documents uploaded successfully",
"help": "Help",
"faqs": "FAQs",
"contactUs": "Contact Us",
"termPrivacy": "Term & Privacy",
"inviteFriends": "Invite Friends",
"more": "More",
"language": "Language",
"mySubscriptions": "My Subscriptions",
"subscriptions": "Subscriptions",
"defineLicenses": "Define Licenses",
"logOut": "Log Out",
"customer": "Customer",
"accept": "Accept"
}; };
static const Map<String, Map<String,dynamic>> mapLocales = {"ar_SA": ar_SA, "en_US": en_US}; static const Map<String, Map<String,dynamic>> mapLocales = {"ar_SA": ar_SA, "en_US": en_US};
} }

@ -489,5 +489,62 @@ abstract class LocaleKeys {
static const searchByService = 'searchByService'; static const searchByService = 'searchByService';
static const selectServices = 'selectServices'; static const selectServices = 'selectServices';
static const modifyPackage = 'modifyPackage'; static const modifyPackage = 'modifyPackage';
static const schedule = 'schedule';
static const serviceLocation = 'serviceLocation';
static const workshop = 'workshop';
static const itemsSelected = 'itemsSelected';
static const workshopFullAccessServices = 'workshopFullAccessServices';
static const changeLocationService = 'changeLocationService';
static const noItemstoShow = 'noItemstoShow';
static const someDescriptionSubServices = 'someDescriptionSubServices';
static const selectServicesYouWant = 'selectServicesYouWant';
static const selectServiceType = 'selectServiceType';
static const selectDateAndTime = 'selectDateAndTime';
static const reviewAppointment = 'reviewAppointment';
static const carEngineCheck = 'carEngineCheck';
static const dateAndTime = 'dateAndTime';
static const timeLocation = 'timeLocation';
static const serviceCharges = 'serviceCharges';
static const locationCharges = 'locationCharges';
static const payableNow = 'payableNow';
static const remainingAmount = 'remainingAmount';
static const branchesFilter = 'branchesFilter';
static const searchByDistance = 'searchByDistance';
static const searchByMinimumRatings = 'searchByMinimumRatings';
static const chat = 'chat';
static const noRequestsShow = 'noRequestsShow';
static const typeMessageHere = 'typeMessageHere';
static const reject = 'reject';
static const newOfferRequired = 'newOfferRequired';
static const offerHasBeenAccepted = 'offerHasBeenAccepted';
static const offerHasBeenRejected = 'offerHasBeenRejected';
static const offerHasBeenCancelled = 'offerHasBeenCancelled';
static const paymentMethod = 'paymentMethod';
static const selectPaymentMethod = 'selectPaymentMethod';
static const password = 'password';
static const customerName = 'customerName';
static const createRequest = 'createRequest';
static const requestType = 'requestType';
static const brand = 'brand';
static const year = 'year';
static const price = 'price';
static const shippingDelivery = 'shippingDelivery';
static const offers = 'offers';
static const noOffersShow = 'noOffersShow';
static const allDocumentMandatoryDealershipProvider = 'allDocumentMandatoryDealershipProvider';
static const documentsUploadedSuccessfully = 'documentsUploadedSuccessfully';
static const help = 'help';
static const faqs = 'faqs';
static const contactUs = 'contactUs';
static const termPrivacy = 'termPrivacy';
static const inviteFriends = 'inviteFriends';
static const more = 'more';
static const language = 'language';
static const mySubscriptions = 'mySubscriptions';
static const subscriptions = 'subscriptions';
static const defineLicenses = 'defineLicenses';
static const logOut = 'logOut';
static const customer = 'customer';
static const accept = 'accept';
} }

@ -27,15 +27,13 @@ class SubscriptionsVM extends BaseVM {
getAllAvailableSubscriptions(String? serviceProviderID) async { getAllAvailableSubscriptions(String? serviceProviderID) async {
selectedIndex = 0; selectedIndex = 0;
setState(ViewState.busy); setState(ViewState.busy);
allSubscriptions = allSubscriptions = await subscriptionRepo.getAllSubscriptions(serviceProviderID);
await subscriptionRepo.getAllSubscriptions(serviceProviderID);
if (allSubscriptions.messageStatus == 1) { if (allSubscriptions.messageStatus == 1) {
monthlyTabs.clear(); monthlyTabs.clear();
var idSet = <int>{}; var idSet = <int>{};
for (var d in allSubscriptions.data ?? []) { for (var d in allSubscriptions.data ?? []) {
if (idSet.add(d.durationDays ?? 0)) { if (idSet.add(d.durationDays ?? 0)) {
monthlyTabs.add(DropValue( monthlyTabs.add(DropValue(d.durationDays, _convertDaysToMonths(d.durationDays ?? 0), ""));
d.durationDays, _convertDaysToMonths(d.durationDays ?? 0), ""));
} }
} }
monthlyTabs.sort((a, b) => a.value.compareTo(b.value)); monthlyTabs.sort((a, b) => a.value.compareTo(b.value));
@ -50,15 +48,13 @@ class SubscriptionsVM extends BaseVM {
getSubscriptionBySP(String serviceProviderID, bool isRenew) async { getSubscriptionBySP(String serviceProviderID, bool isRenew) async {
selectedIndex = 0; selectedIndex = 0;
setState(ViewState.busy); setState(ViewState.busy);
allSubscriptions = allSubscriptions = await subscriptionRepo.getSubscriptionBySP(serviceProviderID, isRenew);
await subscriptionRepo.getSubscriptionBySP(serviceProviderID, isRenew);
if (allSubscriptions.messageStatus == 1) { if (allSubscriptions.messageStatus == 1) {
monthlyTabs.clear(); monthlyTabs.clear();
var idSet = <int>{}; var idSet = <int>{};
for (var d in allSubscriptions.data ?? []) { for (var d in allSubscriptions.data ?? []) {
if (idSet.add(d.durationDays ?? 0)) { if (idSet.add(d.durationDays ?? 0)) {
monthlyTabs.add(DropValue( monthlyTabs.add(DropValue(d.durationDays, _convertDaysToMonths(d.durationDays ?? 0), ""));
d.durationDays, _convertDaysToMonths(d.durationDays ?? 0), ""));
} }
} }
monthlyTabs.sort((a, b) => a.value.compareTo(b.value)); monthlyTabs.sort((a, b) => a.value.compareTo(b.value));
@ -72,11 +68,9 @@ class SubscriptionsVM extends BaseVM {
String newPrice = ""; String newPrice = "";
calculationUpgradePrice( calculationUpgradePrice(String? serviceProviderID, String? newSubscription) async {
String? serviceProviderID, String? newSubscription) async {
setState(ViewState.busy); setState(ViewState.busy);
MResponse mResponse = await subscriptionRepo.calculationUpgradePrice( MResponse mResponse = await subscriptionRepo.calculationUpgradePrice(serviceProviderID, newSubscription);
serviceProviderID, newSubscription);
if (mResponse.messageStatus == 1) { if (mResponse.messageStatus == 1) {
setState(ViewState.idle); setState(ViewState.idle);
newPrice = mResponse.data.toString(); newPrice = mResponse.data.toString();
@ -85,18 +79,13 @@ class SubscriptionsVM extends BaseVM {
} }
} }
Future<MResponse> payForSubscription( Future<MResponse> payForSubscription(int subscriptionId, bool isStartNow, bool isReview, String amount, {bool isDegrade = false, List<int>? listOfBranches, List<int>? listOfUsers}) async {
int subscriptionId, bool isStartNow, bool isReview, String amount,
{bool isDegrade = false,
List<int>? listOfBranches,
List<int>? listOfUsers}) async {
Map<String, dynamic> map; Map<String, dynamic> map;
if (isDegrade) { if (isDegrade) {
map = { map = {
// "id": subscription.id.toString(), // "id": subscription.id.toString(),
// "payFortOrderID": 0, // "payFortOrderID": 0,
"providerID": "providerID": AppState().getUser.data?.userInfo?.providerId.toString() ?? "",
AppState().getUser.data?.userInfo?.providerId.toString() ?? "",
"subscriptionID": subscriptionId.toString(), "subscriptionID": subscriptionId.toString(),
"isStartNow": isStartNow.toString(), "isStartNow": isStartNow.toString(),
"subscriptionAmount": amount, "subscriptionAmount": amount,
@ -108,8 +97,7 @@ class SubscriptionsVM extends BaseVM {
map = { map = {
// "id": subscription.id.toString(), // "id": subscription.id.toString(),
// "payFortOrderID": 0, // "payFortOrderID": 0,
"providerID": "providerID": AppState().getUser.data?.userInfo?.providerId.toString() ?? "",
AppState().getUser.data?.userInfo?.providerId.toString() ?? "",
"subscriptionID": subscriptionId.toString(), "subscriptionID": subscriptionId.toString(),
"isStartNow": isStartNow.toString(), "isStartNow": isStartNow.toString(),
"subscriptionAmount": amount, "subscriptionAmount": amount,
@ -118,8 +106,23 @@ class SubscriptionsVM extends BaseVM {
// "listOfUsers": [] // "listOfUsers": []
}; };
} }
MResponse mResponse = MResponse mResponse = await subscriptionRepo.payForProviderSubscription(map);
await subscriptionRepo.payForProviderSubscription(map); return mResponse;
}
Future<MResponse> createSubscriptionOrder(int subscriptionId, bool isStartNow, bool isReview, String amount, {bool isDegrade = false, List<int>? listOfBranches, List<int>? listOfUsers}) async {
Map<String, dynamic> map = {
// "id": subscription.id.toString(),
// "payFortOrderID": 0,
"providerID": AppState().getUser.data?.userInfo?.providerId.toString() ?? "",
"subscriptionID": subscriptionId.toString(),
"isStartNow": isStartNow.toString(),
"subscriptionAmount": amount,
"isRenew": isReview.toString()
// "listOfBranches": [],
// "listOfUsers": []
};
MResponse mResponse = await subscriptionRepo.payForProviderSubscription(map);
return mResponse; return mResponse;
} }
@ -130,8 +133,7 @@ class SubscriptionsVM extends BaseVM {
Map<String, String> map = { Map<String, String> map = {
// "id": subscription.id.toString(), // "id": subscription.id.toString(),
// "payFortOrderID": 0, // "payFortOrderID": 0,
"providerID": "providerID": AppState().getUser.data?.userInfo?.providerId.toString() ?? "",
AppState().getUser.data?.userInfo?.providerId.toString() ?? "",
// "listOfBranches": [], // "listOfBranches": [],
// "listOfUsers": [] // "listOfUsers": []
}; };
@ -146,12 +148,8 @@ class SubscriptionsVM extends BaseVM {
final int months = days ~/ 30; final int months = days ~/ 30;
final int remainingDays = days % 30; final int remainingDays = days % 30;
String _result = months > 0 String _result = months > 0 ? '$months Month${months > 1 ? 's' : ''}${remainingDays > 0 ? ' & ' : ''}' : '';
? '$months Month${months > 1 ? 's' : ''}${remainingDays > 0 ? ' & ' : ''}' _result += remainingDays > 0 ? '$remainingDays Day${remainingDays > 1 ? 's' : ''}' : '';
: '';
_result += remainingDays > 0
? '$remainingDays Day${remainingDays > 1 ? 's' : ''}'
: '';
return _result; return _result;
} }
@ -169,8 +167,7 @@ class SubscriptionsVM extends BaseVM {
selectedIndex = 0; selectedIndex = 0;
setState(ViewState.busy); setState(ViewState.busy);
// allSubscriptions = await subscriptionRepo.getAllSubscriptions(serviceProviderID); // allSubscriptions = await subscriptionRepo.getAllSubscriptions(serviceProviderID);
allSubscriptions = allSubscriptions = await subscriptionRepo.getMySubscriptions(serviceProviderID);
await subscriptionRepo.getMySubscriptions(serviceProviderID);
if (allSubscriptions.messageStatus == 1) { if (allSubscriptions.messageStatus == 1) {
// allSubscriptions.data!.sort((a, b) => a.value.compareTo(b.value)); // allSubscriptions.data!.sort((a, b) => a.value.compareTo(b.value));
setState(ViewState.idle); setState(ViewState.idle);

@ -53,6 +53,14 @@ class UserVM extends BaseVM {
bool completeProfilePageCheckbox = false; bool completeProfilePageCheckbox = false;
bool _loginOtherAccount = false;
bool get loginOtherAccount => _loginOtherAccount;
set loginOtherAccount(bool value) {
_loginOtherAccount = value;
}
void updateCompleteProfilePageCheckbox(bool newValue) { void updateCompleteProfilePageCheckbox(bool newValue) {
completeProfilePageCheckbox = newValue; completeProfilePageCheckbox = newValue;
notifyListeners(); notifyListeners();
@ -155,8 +163,7 @@ class UserVM extends BaseVM {
} }
} }
Future<void> performCompleteProfile( Future<void> performCompleteProfile(BuildContext context, {
BuildContext context, {
required String password, required String password,
required String confirmPassword, required String confirmPassword,
required String firstName, required String firstName,
@ -515,8 +522,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));
@ -524,8 +531,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 {
@ -620,9 +627,7 @@ class UserVM extends BaseVM {
Future<void> isAlreadyUserLoggedin(BuildContext context) async { Future<void> isAlreadyUserLoggedin(BuildContext context) async {
String uName = await SharedPrefManager.getPhoneOrEmail(); String uName = await SharedPrefManager.getPhoneOrEmail();
String pass = await SharedPrefManager.getUserPassword(); String pass = await SharedPrefManager.getUserPassword();
if (!loginOtherAccount && uName.isNotEmpty && pass.isNotEmpty) {
if (uName.isNotEmpty && pass.isNotEmpty) {
logger.d(uName);
if (uName.isNum()) { if (uName.isNum()) {
performBasicOtpLoginWithPasswordPage(context, type: ClassType.NUMBER, countryCode: null, phoneNum: uName, password: pass); performBasicOtpLoginWithPasswordPage(context, type: ClassType.NUMBER, countryCode: null, phoneNum: uName, password: pass);
} }
@ -632,4 +637,9 @@ class UserVM extends BaseVM {
logger.d("Skip Login Triggered"); logger.d("Skip Login Triggered");
} }
} }
void otherLogin(BuildContext context) {
_loginOtherAccount = true;
navigateReplaceWithName(context, AppRoutes.loginWithPassword);
}
} }

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.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/models/appointments_models/service_schedule_model.dart'; import 'package:mc_common_app/models/appointments_models/service_schedule_model.dart';
import 'package:mc_common_app/models/services_models/service_model.dart'; import 'package:mc_common_app/models/services_models/service_model.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
@ -11,6 +12,7 @@ import 'package:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/common_widgets/time_slots.dart'; import 'package:mc_common_app/widgets/common_widgets/time_slots.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart';
class ScreenArgumentsForAppointmentDetailPage { class ScreenArgumentsForAppointmentDetailPage {
final int routeFlag; // 1 = coming from create appointment || 2 = coming from reschedule appointment final int routeFlag; // 1 = coming from create appointment || 2 = coming from reschedule appointment
@ -28,7 +30,7 @@ class BookAppointmentSchedulesView extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: CustomAppBar( appBar: CustomAppBar(
title: "Book Appointment", title: LocaleKeys.bookAppointment.tr(),
isRemoveBackButton: false, isRemoveBackButton: false,
isDrawerEnabled: false, isDrawerEnabled: false,
onBackButtonTapped: () => Navigator.pop(context), onBackButtonTapped: () => Navigator.pop(context),
@ -52,15 +54,15 @@ class BookAppointmentSchedulesView extends StatelessWidget {
Row( Row(
children: [ children: [
Expanded( Expanded(
child: "Schedule ${scheduleIndex + 1}".toText(fontSize: 20, isBold: true), child: (LocaleKeys.schedule.tr() + " ${scheduleIndex + 1}").toText(fontSize: 20, isBold: true),
), ),
], ],
), ),
Row( Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
"Service Location: ".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), (LocaleKeys.serviceLocation.tr()).toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true),
("${scheduleData.appointmentType == 2 ? "Home" : "Workshop"}").toText(fontSize: 12, isBold: true).expand(), ("${scheduleData.appointmentType == 2 ? LocaleKeys.home.tr() : LocaleKeys.workshop.tr()}").toText(fontSize: 12, isBold: true).expand(),
], ],
), ),
Column( Column(
@ -100,7 +102,7 @@ class BookAppointmentSchedulesView extends StatelessWidget {
Row( Row(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
("Available Slots").toText(fontSize: 14, isBold: true), (LocaleKeys.availableSlots.tr()).toText(fontSize: 14, isBold: true),
], ],
), ),
5.height, 5.height,
@ -128,7 +130,7 @@ class BookAppointmentSchedulesView extends StatelessWidget {
child: ShowFillButton( child: ShowFillButton(
txtColor: MyColors.black, txtColor: MyColors.black,
maxHeight: 55, maxHeight: 55,
title: "Cancel", title: LocaleKeys.cancel.tr(),
onPressed: () => Navigator.pop(context), onPressed: () => Navigator.pop(context),
backgroundColor: MyColors.greyButtonColor, backgroundColor: MyColors.greyButtonColor,
), ),
@ -137,7 +139,7 @@ class BookAppointmentSchedulesView extends StatelessWidget {
Expanded( Expanded(
child: ShowFillButton( child: ShowFillButton(
maxHeight: 55, maxHeight: 55,
title: screenArgumentsForAppointmentDetailPage.routeFlag == 1 ? "Review" : "Confirm", title: screenArgumentsForAppointmentDetailPage.routeFlag == 1 ? LocaleKeys.review.tr() : LocaleKeys.confirm.tr(),
onPressed: () { onPressed: () {
if (screenArgumentsForAppointmentDetailPage.routeFlag == 1) { if (screenArgumentsForAppointmentDetailPage.routeFlag == 1) {
appointmentsVM.onReviewButtonPressed(context); appointmentsVM.onReviewButtonPressed(context);

@ -1,6 +1,9 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/widgets.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/models/services_models/item_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/services_models/service_model.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
@ -10,6 +13,7 @@ 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/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart';
class BookAppointmentServicesView extends StatelessWidget { class BookAppointmentServicesView extends StatelessWidget {
BookAppointmentServicesView({Key? key}) : super(key: key); BookAppointmentServicesView({Key? key}) : super(key: key);
@ -18,7 +22,7 @@ class BookAppointmentServicesView extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: CustomAppBar( appBar: CustomAppBar(
title: "Book Appointment", title: LocaleKeys.bookAppointment.tr(),
isRemoveBackButton: false, isRemoveBackButton: false,
isDrawerEnabled: false, isDrawerEnabled: false,
onBackButtonTapped: () { onBackButtonTapped: () {
@ -27,7 +31,8 @@ class BookAppointmentServicesView extends StatelessWidget {
}, },
), ),
body: Consumer( body: Consumer(
builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) { builder: (BuildContext context, AppointmentsVM appointmentsVM,
Widget? child) {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -35,12 +40,14 @@ class BookAppointmentServicesView extends StatelessWidget {
CustomAddButton( CustomAddButton(
needsBorder: true, needsBorder: true,
bgColor: MyColors.white, bgColor: MyColors.white,
onTap: () => appointmentsVM.openTheAddServiceBottomSheet(context, appointmentsVM), onTap: () => appointmentsVM.openTheAddServiceBottomSheet(
text: "Add Services", context, appointmentsVM),
text: LocaleKeys.addServices.tr(),
icon: Container( icon: Container(
height: 24, height: 24,
width: 24, width: 24,
decoration: const BoxDecoration(shape: BoxShape.circle, color: MyColors.darkTextColor), decoration: const BoxDecoration(
shape: BoxShape.circle, color: MyColors.darkTextColor),
child: const Icon(Icons.add, color: MyColors.white), child: const Icon(Icons.add, color: MyColors.white),
), ),
).horPaddingMain(), ).horPaddingMain(),
@ -49,17 +56,22 @@ class BookAppointmentServicesView extends StatelessWidget {
shrinkWrap: true, shrinkWrap: true,
itemCount: appointmentsVM.servicesInCurrentAppointment.length, itemCount: appointmentsVM.servicesInCurrentAppointment.length,
itemBuilder: (BuildContext context, int serviceIndex) { itemBuilder: (BuildContext context, int serviceIndex) {
ServiceModel serviceData = appointmentsVM.servicesInCurrentAppointment[serviceIndex]; ServiceModel serviceData = appointmentsVM
.servicesInCurrentAppointment[serviceIndex];
return Column( return Column(
children: [ children: [
Row( Row(
children: [ children: [
Expanded( Expanded(
child: (serviceData.serviceDescription ?? "").toText(fontSize: 15, isBold: true), child: (serviceData.serviceDescription ?? "")
.toText(fontSize: 15, isBold: true),
), ),
IconButton( IconButton(
onPressed: () => appointmentsVM.removeServiceInCurrentAppointment(serviceIndex), onPressed: () => appointmentsVM
icon: Icon(Icons.delete_outline, color: MyColors.redColor), .removeServiceInCurrentAppointment(
serviceIndex),
icon: Icon(Icons.delete_outline,
color: MyColors.redColor),
) )
], ],
), ),
@ -67,19 +79,33 @@ class BookAppointmentServicesView extends StatelessWidget {
Row( Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
"Service Location: ".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), (LocaleKeys.serviceLocation.tr()).toText(
(serviceData.isHomeSelected ? serviceData.homeLocation : "Workshop").toText(fontSize: 12, isBold: true).expand(), fontSize: 12,
color: MyColors.lightTextColor,
isBold: true),
(serviceData.isHomeSelected
? serviceData.homeLocation
: LocaleKeys.workshop.tr())
.toText(fontSize: 12, isBold: true)
.expand(),
], ],
), ),
5.height, 5.height,
Column( Column(
children: List.generate(serviceData.serviceItems!.length, (itemIndex) { children: List.generate(
ItemData itemData = serviceData.serviceItems![itemIndex]; serviceData.serviceItems!.length, (itemIndex) {
ItemData itemData =
serviceData.serviceItems![itemIndex];
return Row( return Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
"${itemData.name}: ".toText(fontSize: 13, color: MyColors.lightTextColor, isBold: true), "${itemData.name}: ".toText(
("${itemData.price}").toText(fontSize: 13, isBold: true).expand(), fontSize: 13,
color: MyColors.lightTextColor,
isBold: true),
("${itemData.price}")
.toText(fontSize: 13, isBold: true)
.expand(),
], ],
); );
}), }),
@ -88,18 +114,33 @@ class BookAppointmentServicesView extends StatelessWidget {
Row( Row(
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
((appointmentsVM.servicesInCurrentAppointment[serviceIndex].currentTotalServicePrice).toString()).toText(fontSize: 32, isBold: true), ((appointmentsVM
.servicesInCurrentAppointment[
serviceIndex]
.currentTotalServicePrice)
.toString())
.toText(fontSize: 32, isBold: true),
2.width, 2.width,
"SAR".toText(color: MyColors.lightTextColor, fontSize: 16, isBold: true).paddingOnly(bottom: 5), LocaleKeys.sar
Icon( .tr()
Icons.arrow_drop_down, .toText(
size: 30, color: MyColors.lightTextColor,
) fontSize: 16,
isBold: true)
.paddingOnly(bottom: 5),
Icon(Icons.arrow_drop_down, size: 30)
], ],
).onPress(() => appointmentsVM.priceBreakDownClicked(context, appointmentsVM.servicesInCurrentAppointment[serviceIndex])), ).onPress(() => appointmentsVM.priceBreakDownClicked(
context,
appointmentsVM
.servicesInCurrentAppointment[serviceIndex])),
], ],
], ],
).toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 10)); ).toWhiteContainer(
width: double.infinity,
allPading: 12,
margin: const EdgeInsets.symmetric(
horizontal: 21, vertical: 10));
}, },
).expand(), ).expand(),
Row( Row(
@ -108,7 +149,7 @@ class BookAppointmentServicesView extends StatelessWidget {
child: ShowFillButton( child: ShowFillButton(
txtColor: MyColors.black, txtColor: MyColors.black,
maxHeight: 55, maxHeight: 55,
title: "Cancel", title: LocaleKeys.cancel.tr(),
onPressed: () { onPressed: () {
appointmentsVM.servicesInCurrentAppointment.clear(); appointmentsVM.servicesInCurrentAppointment.clear();
appointmentsVM.allSelectedItemsInAppointments.clear(); appointmentsVM.allSelectedItemsInAppointments.clear();
@ -121,7 +162,7 @@ class BookAppointmentServicesView extends StatelessWidget {
Expanded( Expanded(
child: ShowFillButton( child: ShowFillButton(
maxHeight: 55, maxHeight: 55,
title: "Next", title: LocaleKeys.next.tr(),
onPressed: () { onPressed: () {
appointmentsVM.onServicesNextPressed(context); appointmentsVM.onServicesNextPressed(context);
}, },

@ -1,8 +1,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/classes/consts.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/models/services_models/item_model.dart'; import 'package:mc_common_app/models/services_models/item_model.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/utils/navigator.dart';
@ -12,6 +12,7 @@ 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/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart';
class BookAppointmentsItemView extends StatelessWidget { class BookAppointmentsItemView extends StatelessWidget {
const BookAppointmentsItemView({Key? key}) : super(key: key); const BookAppointmentsItemView({Key? key}) : super(key: key);
@ -20,14 +21,15 @@ class BookAppointmentsItemView extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: CustomAppBar( appBar: CustomAppBar(
title: "Select Items", title: LocaleKeys.selectItems.tr(),
isRemoveBackButton: false, isRemoveBackButton: false,
isDrawerEnabled: false, isDrawerEnabled: false,
actions: [MyAssets.searchIcon.buildSvg().paddingOnly(right: 21)], actions: [MyAssets.searchIcon.buildSvg().paddingOnly(right: 21)],
onBackButtonTapped: () => Navigator.pop(context), onBackButtonTapped: () => Navigator.pop(context),
), ),
body: Consumer( body: Consumer(
builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) { builder: (BuildContext context, AppointmentsVM appointmentsVM,
Widget? child) {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -36,18 +38,30 @@ class BookAppointmentsItemView extends StatelessWidget {
width: double.infinity, width: double.infinity,
color: MyColors.darkTextColor, color: MyColors.darkTextColor,
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: "${appointmentsVM.selectedSubServicesCounter} Item(s) Selected".toText(fontSize: 16, color: MyColors.white).horPaddingMain(), child: ("${appointmentsVM.selectedSubServicesCounter} " +
LocaleKeys.itemsSelected.tr())
.toText(fontSize: 16, color: MyColors.white)
.horPaddingMain(),
), ),
16.height, 16.height,
Column( Column(
children: [ children: [
"Few services are not available on home location. Change the location to workshop to full access the services".toText(fontSize: 12, isItalic: true, color: MyColors.lightTextColor), LocaleKeys.workshopFullAccessServices.tr().toText(
fontSize: 12,
isItalic: true,
color: MyColors.lightTextColor),
8.height, 8.height,
Row( Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
"Change location or service: ".toText(fontSize: 14, isBold: true), LocaleKeys.changeLocationService
"Edit".toText(fontSize: 14, isBold: true, isUnderLine: true, color: MyColors.adPendingStatusColor), .tr()
.toText(fontSize: 14, isBold: true),
LocaleKeys.edit.tr().toText(
fontSize: 14,
isBold: true,
isUnderLine: true,
color: MyColors.adPendingStatusColor),
5.width, 5.width,
MyAssets.icEdit.buildSvg(width: 17), MyAssets.icEdit.buildSvg(width: 17),
], ],
@ -57,26 +71,41 @@ class BookAppointmentsItemView extends StatelessWidget {
], ],
).horPaddingMain(), ).horPaddingMain(),
appointmentsVM.serviceItemsFromApi.isEmpty appointmentsVM.serviceItemsFromApi.isEmpty
? Expanded(child: Center(child: "No Items to show.".toText(fontSize: 16, color: MyColors.lightTextColor))) ? Expanded(
child: Center(
child: LocaleKeys.noItemstoShow.toText(
fontSize: 16, color: MyColors.lightTextColor)))
: ListView.separated( : ListView.separated(
separatorBuilder: (BuildContext context, int index) => Divider(), separatorBuilder: (BuildContext context, int index) =>
Divider(),
itemCount: appointmentsVM.serviceItemsFromApi.length, itemCount: appointmentsVM.serviceItemsFromApi.length,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
ItemData itemData = appointmentsVM.serviceItemsFromApi[index]; ItemData itemData =
appointmentsVM.serviceItemsFromApi[index];
return ServiceItemWithPriceCheckBox( return ServiceItemWithPriceCheckBox(
description: itemData.description ?? "Some description about the sub-services", description: itemData.description ??
LocaleKeys.someDescriptionSubServices.tr(),
title: itemData.name!, title: itemData.name!,
isSelected: itemData.isUpdateOrSelected!, isSelected: itemData.isUpdateOrSelected!,
onSelection: (bool value) { onSelection: (bool value) {
print("itemId: ${itemData.id}"); print("itemId: ${itemData.id}");
appointmentsVM.onItemUpdateOrSelected(index, !itemData.isUpdateOrSelected!, itemData.id!); appointmentsVM.onItemUpdateOrSelected(index,
!itemData.isUpdateOrSelected!, itemData.id!);
}, },
priceWidget: Row( priceWidget: Row(
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
// TODO: This Price will be decided according to the service selected itemData.price!
itemData.price!.split(".").first.toText(fontSize: 30, isBold: true), .split(".")
" SAR".toText(fontSize: 15, isBold: true, color: MyColors.lightTextColor).paddingOnly(bottom: 5), .first
.toText(fontSize: 30, isBold: true),
LocaleKeys.sar
.tr()
.toText(
fontSize: 15,
isBold: true,
color: MyColors.lightTextColor)
.paddingOnly(bottom: 5),
], ],
), ),
); );
@ -93,7 +122,8 @@ class BookAppointmentsItemView extends StatelessWidget {
Row( Row(
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end,
children: [ children: [
appointmentsVM.selectSubServicesError.toText(fontSize: 14, color: Colors.red), appointmentsVM.selectSubServicesError
.toText(fontSize: 14, color: Colors.red),
], ],
).paddingOnly(right: 10), ).paddingOnly(right: 10),
8.height, 8.height,
@ -103,9 +133,10 @@ class BookAppointmentsItemView extends StatelessWidget {
child: ShowFillButton( child: ShowFillButton(
txtColor: MyColors.black, txtColor: MyColors.black,
maxHeight: 55, maxHeight: 55,
title: "Cancel", title: LocaleKeys.cancel.tr(),
onPressed: () { onPressed: () {
appointmentsVM.resetCategorySelectionBottomSheet(); appointmentsVM
.resetCategorySelectionBottomSheet();
pop(context); pop(context);
}, },
backgroundColor: MyColors.greyButtonColor, backgroundColor: MyColors.greyButtonColor,
@ -117,9 +148,10 @@ class BookAppointmentsItemView extends StatelessWidget {
builder: (BuildContext context) { builder: (BuildContext context) {
return ShowFillButton( return ShowFillButton(
maxHeight: 55, maxHeight: 55,
title: "Next", title: LocaleKeys.next.tr(),
onPressed: () async { onPressed: () async {
bool resp = appointmentsVM.validateItemsSelection(); bool resp =
appointmentsVM.validateItemsSelection();
if (resp) { if (resp) {
appointmentsVM.onItemsSelectedInService(); appointmentsVM.onItemsSelectedInService();
Navigator.pop(context); Navigator.pop(context);
@ -133,7 +165,10 @@ class BookAppointmentsItemView extends StatelessWidget {
// Navigator.of(context).pushReplacementNamed(AppRoutes.bookAppointmenServicesView); // Navigator.of(context).pushReplacementNamed(AppRoutes.bookAppointmenServicesView);
// } // }
}, },
backgroundColor: !appointmentsVM.isServiceSelectionValidated() ? MyColors.lightTextColor.withOpacity(0.6) : MyColors.darkPrimaryColor, backgroundColor: !appointmentsVM
.isServiceSelectionValidated()
? MyColors.lightTextColor.withOpacity(0.6)
: MyColors.darkPrimaryColor,
); );
}, },
), ),

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/classes/consts.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/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/widgets/button/show_fill_button.dart'; import 'package:mc_common_app/widgets/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';
@ -9,6 +10,7 @@ import 'package:mc_common_app/widgets/common_widgets/provider_details_card.dart'
import 'package:mc_common_app/widgets/common_widgets/time_slots.dart'; import 'package:mc_common_app/widgets/common_widgets/time_slots.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.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:easy_localization/easy_localization.dart';
class BookProviderAppView extends StatefulWidget { class BookProviderAppView extends StatefulWidget {
const BookProviderAppView({Key? key}) : super(key: key); const BookProviderAppView({Key? key}) : super(key: key);
@ -24,7 +26,7 @@ class _BookProviderAppViewState extends State<BookProviderAppView> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: CustomAppBar( appBar: CustomAppBar(
title: "Appointment", title: LocaleKeys.appointment.tr(),
profileImageUrl: MyAssets.bnCar, profileImageUrl: MyAssets.bnCar,
isRemoveBackButton: false, isRemoveBackButton: false,
isDrawerEnabled: false, isDrawerEnabled: false,
@ -46,7 +48,9 @@ class _BookProviderAppViewState extends State<BookProviderAppView> {
providerRatings: "4.9", providerRatings: "4.9",
), ),
12.height, 12.height,
isReview ? ReviewAppointmentSection() : ServicesSelectionSection(), isReview
? ReviewAppointmentSection()
: ServicesSelectionSection(),
10.height, 10.height,
], ],
), ),
@ -55,7 +59,7 @@ class _BookProviderAppViewState extends State<BookProviderAppView> {
Padding( Padding(
padding: const EdgeInsets.only(bottom: 10, left: 21, right: 21), padding: const EdgeInsets.only(bottom: 10, left: 21, right: 21),
child: ShowFillButton( child: ShowFillButton(
title: "Book Appointment", title: LocaleKeys.bookAppointment.tr(),
maxWidth: double.infinity, maxWidth: double.infinity,
onPressed: () { onPressed: () {
isReview = !isReview; isReview = !isReview;
@ -87,44 +91,47 @@ class ServicesSelectionSection extends StatelessWidget {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
"Select services you want".toText(fontSize: 18, isBold: true), LocaleKeys.selectServicesYouWant
.tr()
.toText(fontSize: 18, isBold: true),
8.height, 8.height,
DropdownField( DropdownField(
(DropValue value) {}, (DropValue value) {},
list: dropList, list: dropList,
hint: "Select service type", hint: LocaleKeys.selectServiceType.tr(),
), ),
8.height, 8.height,
DropdownField( DropdownField(
(DropValue value) {}, (DropValue value) {},
list: dropList, list: dropList,
hint: "Select service type", hint: LocaleKeys.selectServiceType.tr(),
), ),
8.height, 8.height,
DropdownField( DropdownField(
(DropValue value) {}, (DropValue value) {},
list: dropList, list: dropList,
hint: "Select service type", hint: LocaleKeys.selectServiceType.tr(),
), ),
22.height, 22.height,
"Select date and time".toText(fontSize: 18, isBold: true), LocaleKeys.selectDateAndTime.tr().toText(fontSize: 18, isBold: true),
8.height, 8.height,
DropdownField( DropdownField(
(DropValue value) {}, (DropValue value) {},
list: dropList, list: dropList,
hint: "Select service type", hint: LocaleKeys.selectServiceType.tr(),
), ),
22.height, 22.height,
"Available slots".toText(fontSize: 15, isBold: true), LocaleKeys.availableSlots.tr().toText(fontSize: 15, isBold: true),
8.height, 8.height,
BuildTimeSlots(onPressed: (index) {}, timeSlots: []), BuildTimeSlots(onPressed: (index) {}, timeSlots: []),
22.height, 22.height,
"Total Amount".toText(fontSize: 18, isBold: true), LocaleKeys.totalAmount.tr().toText(fontSize: 18, isBold: true),
Row( Row(
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
"3000".toText(fontSize: 20, isBold: true), "3000".toText(fontSize: 20, isBold: true),
"SAR".toText(fontSize: 10, isBold: true, color: MyColors.lightTextColor), LocaleKeys.sar.tr().toText(
fontSize: 10, isBold: true, color: MyColors.lightTextColor),
], ],
), ),
10.height, 10.height,
@ -144,20 +151,24 @@ class ReviewAppointmentSection extends StatelessWidget {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
"Review Appointment".toText(fontSize: 18, isBold: true), LocaleKeys.reviewAppointment.tr().toText(fontSize: 18, isBold: true),
15.height, 15.height,
"Services".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor), LocaleKeys.services.tr().toText(
"Car Engine Check".toText(fontSize: 18, isBold: true), fontSize: 14, isBold: true, color: MyColors.lightTextColor),
LocaleKeys.carEngineCheck.tr().toText(fontSize: 18, isBold: true),
13.height, 13.height,
"Date and Time".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor), LocaleKeys.dateAndTime.tr().toText(
fontSize: 14, isBold: true, color: MyColors.lightTextColor),
"2 Feb, 2023 at 09:00am".toText(fontSize: 18, isBold: true), "2 Feb, 2023 at 09:00am".toText(fontSize: 18, isBold: true),
13.height, 13.height,
"Total Amount".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor), LocaleKeys.totalAmount.tr().toText(
fontSize: 14, isBold: true, color: MyColors.lightTextColor),
Row( Row(
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
"3000".toText(fontSize: 20, isBold: true), "3000".toText(fontSize: 20, isBold: true),
"SAR".toText(fontSize: 10, isBold: true, color: MyColors.lightTextColor), LocaleKeys.sar.tr().toText(
fontSize: 10, isBold: true, color: MyColors.lightTextColor),
], ],
), ),
100.height, 100.height,

@ -1,6 +1,6 @@
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/classes/consts.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';
@ -48,12 +48,17 @@ class ReviewAppointment extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
(appointmentsVM.selectedBranchModel!.branchName ?? "").toText(fontSize: 16, isBold: true), (appointmentsVM.selectedBranchModel!.branchName ??
"")
.toText(fontSize: 16, isBold: true),
Row( Row(
children: [ children: [
LocaleKeys.location.tr().toText(color: MyColors.lightTextColor, fontSize: 12), LocaleKeys.location.tr().toText(
color: MyColors.lightTextColor,
fontSize: 12),
2.width, 2.width,
": ${appointmentsVM.selectedBranchModel!.branchDescription ?? ""}".toText(fontSize: 12), ": ${appointmentsVM.selectedBranchModel!.branchDescription ?? ""}"
.toText(fontSize: 12),
], ],
), ),
], ],
@ -77,7 +82,9 @@ class ReviewAppointment extends StatelessWidget {
), ),
), ),
], ],
).onPress(() {}).toWhiteContainer(width: double.infinity, allPading: 12)); )
.onPress(() {})
.toWhiteContainer(width: double.infinity, allPading: 12));
} }
Widget buildServicesInfoCard({required BuildContext context}) { Widget buildServicesInfoCard({required BuildContext context}) {
@ -86,14 +93,18 @@ class ReviewAppointment extends StatelessWidget {
shrinkWrap: true, shrinkWrap: true,
itemCount: appointmentsVM.serviceAppointmentScheduleList.length, itemCount: appointmentsVM.serviceAppointmentScheduleList.length,
itemBuilder: (BuildContext context, int scheduleIndex) { itemBuilder: (BuildContext context, int scheduleIndex) {
ServiceAppointmentScheduleModel scheduleData = appointmentsVM.serviceAppointmentScheduleList[scheduleIndex]; ServiceAppointmentScheduleModel scheduleData =
appointmentsVM.serviceAppointmentScheduleList[scheduleIndex];
return Column( return Column(
children: [ children: [
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Expanded( Expanded(
child: "Services".toText(fontSize: 14, isBold: true, color: MyColors.lightTextColor), child: LocaleKeys.services.tr().toText(
fontSize: 14,
isBold: true,
color: MyColors.lightTextColor),
), ),
], ],
), ),
@ -106,33 +117,55 @@ class ReviewAppointment extends StatelessWidget {
itemCount: scheduleData.servicesListInAppointment!.length, itemCount: scheduleData.servicesListInAppointment!.length,
itemBuilder: (BuildContext context, int serviceIndex) { itemBuilder: (BuildContext context, int serviceIndex) {
String selectedTimeSlot = ""; String selectedTimeSlot = "";
if (scheduleData.selectedCustomTimeDateSlotModel!.availableSlots != null) { if (scheduleData
selectedTimeSlot = scheduleData.selectedCustomTimeDateSlotModel!.availableSlots!.firstWhere((element) => element.isSelected).slot; .selectedCustomTimeDateSlotModel!.availableSlots !=
null) {
selectedTimeSlot = scheduleData
.selectedCustomTimeDateSlotModel!.availableSlots!
.firstWhere((element) => element.isSelected)
.slot;
} }
return Column( return Column(
children: [ children: [
if (scheduleData.servicesListInAppointment!.isNotEmpty) ...[ if (scheduleData
.servicesListInAppointment!.isNotEmpty) ...[
Column( Column(
children: List.generate(scheduleData.servicesListInAppointment!.length, (serviceIndex) { children: List.generate(
ServiceModel serviceData = scheduleData.servicesListInAppointment![serviceIndex]; scheduleData.servicesListInAppointment!.length,
(serviceIndex) {
ServiceModel serviceData = scheduleData
.servicesListInAppointment![serviceIndex];
return Column( return Column(
children: [ children: [
Row( Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment:
CrossAxisAlignment.start,
children: [ children: [
"${serviceData.providerServiceDescription}".toText(fontSize: 16, isBold: true), "${serviceData.providerServiceDescription}"
.toText(fontSize: 16, isBold: true),
], ],
), ),
Column( Column(
children: List.generate(serviceData.serviceItems!.length, (itemIndex) { children: List.generate(
ItemData itemData = serviceData.serviceItems![itemIndex]; serviceData.serviceItems!.length,
(itemIndex) {
ItemData itemData =
serviceData.serviceItems![itemIndex];
return Column( return Column(
children: [ children: [
Row( Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment:
mainAxisAlignment: MainAxisAlignment.start, CrossAxisAlignment.start,
mainAxisAlignment:
MainAxisAlignment.start,
children: [ children: [
"${itemData.name}: ${itemData.price} SAR".toText(fontSize: 13, isBold: true, color: MyColors.lightTextColor), ("${itemData.name}: ${itemData.price} " +
LocaleKeys.sar.tr())
.toText(
fontSize: 13,
isBold: true,
color: MyColors
.lightTextColor),
], ],
), ),
], ],
@ -150,15 +183,27 @@ class ReviewAppointment extends StatelessWidget {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
"Time & Location".toText(fontSize: 16, isBold: true), LocaleKeys.timeLocation
.tr()
.toText(fontSize: 16, isBold: true),
3.height, 3.height,
Row(children: [ Row(children: [
"Date & Time: ".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), LocaleKeys.dateAndTime.tr().toText(
"${scheduleData.selectedCustomTimeDateSlotModel!.date!.date} at ${selectedTimeSlot}".toText(fontSize: 12, isBold: true), fontSize: 12,
color: MyColors.lightTextColor,
isBold: true),
"${scheduleData.selectedCustomTimeDateSlotModel!.date!.date} at ${selectedTimeSlot}"
.toText(fontSize: 12, isBold: true),
]), ]),
Row(children: [ Row(children: [
"Location: ".toText(fontSize: 12, color: MyColors.lightTextColor, isBold: true), (LocaleKeys.location.tr() + " ").toText(
(scheduleData.appointmentType == 2 ? "Home" : "Workshop").toText(fontSize: 12, isBold: true), fontSize: 12,
color: MyColors.lightTextColor,
isBold: true),
(scheduleData.appointmentType == 2
? LocaleKeys.home.tr()
: LocaleKeys.workshop.tr())
.toText(fontSize: 12, isBold: true),
]), ]),
], ],
), ),
@ -174,20 +219,35 @@ class ReviewAppointment extends StatelessWidget {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
"Amount".toText(fontSize: 16, isBold: true), LocaleKeys.amount
.tr()
.toText(fontSize: 16, isBold: true),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [ children: [
"Service Charges".toText(fontSize: 14, color: MyColors.lightTextColor, isBold: true), LocaleKeys.serviceCharges.tr().toText(
"${scheduleData.amountTotal.toString()} SAR".toText(fontSize: 16, isBold: true), fontSize: 14,
color: MyColors.lightTextColor,
isBold: true),
"${scheduleData.amountTotal.toString()} SAR"
.toText(fontSize: 16, isBold: true),
], ],
), ),
if (scheduleData.appointmentType == 1) ...[ if (scheduleData.appointmentType == 1) ...[
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [ children: [
"Location Charges ($rangePricePerKm x $totalKms )".toText(fontSize: 14, color: MyColors.lightTextColor, isBold: true), (LocaleKeys.locationCharges.tr() +
"${totalServicePrice.toString()} SAR".toText(fontSize: 16, isBold: true), " ($rangePricePerKm x $totalKms )")
.toText(
fontSize: 14,
color: MyColors.lightTextColor,
isBold: true),
("${totalServicePrice.toString()} " +
LocaleKeys.sar.tr())
.toText(fontSize: 16, isBold: true),
], ],
), ),
], ],
@ -198,12 +258,16 @@ class ReviewAppointment extends StatelessWidget {
], ],
); );
}, },
separatorBuilder: (BuildContext context, int index) => Divider(thickness: 2), separatorBuilder: (BuildContext context, int index) =>
Divider(thickness: 2),
).paddingOnly(bottom: 10), ).paddingOnly(bottom: 10),
], ],
), ),
], ],
).toWhiteContainer(width: double.infinity, allPading: 12, margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 0)); ).toWhiteContainer(
width: double.infinity,
allPading: 12,
margin: const EdgeInsets.symmetric(horizontal: 21, vertical: 0));
}, },
); );
} }
@ -221,13 +285,21 @@ class ReviewAppointment extends StatelessWidget {
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
"Payable now".toText(fontSize: 14, isBold: true), LocaleKeys.payableNow.tr().toText(fontSize: 14, isBold: true),
Row( Row(
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
appointmentsVM.amountToPayForAppointment.toString().toText(fontSize: 16, isBold: true), appointmentsVM.amountToPayForAppointment
.toString()
.toText(fontSize: 16, isBold: true),
2.width, 2.width,
"SAR".toText(color: MyColors.lightTextColor, fontSize: 12, isBold: true).paddingOnly(bottom: 2), LocaleKeys.sar
.tr()
.toText(
color: MyColors.lightTextColor,
fontSize: 12,
isBold: true)
.paddingOnly(bottom: 2),
], ],
) )
], ],
@ -235,13 +307,24 @@ class ReviewAppointment extends StatelessWidget {
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
"Remaining Amount".toText(fontSize: 14, isBold: true), LocaleKeys.remainingAmount
.tr()
.toText(fontSize: 14, isBold: true),
Row( Row(
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
(appointmentsVM.totalAmount - appointmentsVM.amountToPayForAppointment).toString().toText(fontSize: 16, isBold: true), (appointmentsVM.totalAmount -
appointmentsVM.amountToPayForAppointment)
.toString()
.toText(fontSize: 16, isBold: true),
2.width, 2.width,
"SAR".toText(color: MyColors.lightTextColor, fontSize: 12, isBold: true).paddingOnly(bottom: 2), LocaleKeys.sar
.tr()
.toText(
color: MyColors.lightTextColor,
fontSize: 12,
isBold: true)
.paddingOnly(bottom: 2),
], ],
) )
], ],
@ -250,13 +333,21 @@ class ReviewAppointment extends StatelessWidget {
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
"Total Amount ".toText(fontSize: 18, isBold: true), LocaleKeys.totalAmount.tr().toText(fontSize: 18, isBold: true),
Row( Row(
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
appointmentsVM.totalAmount.toString().toText(fontSize: 29, isBold: true), appointmentsVM.totalAmount
.toString()
.toText(fontSize: 29, isBold: true),
2.width, 2.width,
"SAR".toText(color: MyColors.lightTextColor, fontSize: 16, isBold: true).paddingOnly(bottom: 5), LocaleKeys.sar
.tr()
.toText(
color: MyColors.lightTextColor,
fontSize: 16,
isBold: true)
.paddingOnly(bottom: 5),
], ],
) )
], ],
@ -267,7 +358,7 @@ class ReviewAppointment extends StatelessWidget {
child: ShowFillButton( child: ShowFillButton(
maxHeight: 55, maxHeight: 55,
backgroundColor: MyColors.darkPrimaryColor, backgroundColor: MyColors.darkPrimaryColor,
title: "Book Appointment", title: LocaleKeys.bookAppointment.tr(),
onPressed: () { onPressed: () {
appointmentsVM.onBookAppointmentPressed(context); appointmentsVM.onBookAppointmentPressed(context);
}, },
@ -282,7 +373,7 @@ class ReviewAppointment extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: CustomAppBar( appBar: CustomAppBar(
title: "Review Appointment", title: LocaleKeys.reviewAppointment.tr(),
isRemoveBackButton: false, isRemoveBackButton: false,
isDrawerEnabled: false, isDrawerEnabled: false,
onBackButtonTapped: () => Navigator.pop(context), onBackButtonTapped: () => Navigator.pop(context),

@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/classes/consts.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/models/general_models/widgets_models.dart'; import 'package:mc_common_app/models/general_models/widgets_models.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/view_models/ad_view_model.dart'; import 'package:mc_common_app/view_models/ad_view_model.dart';
@ -15,6 +16,7 @@ import 'package:mc_common_app/widgets/common_widgets/slider_widget.dart';
import 'package:mc_common_app/widgets/dropdown/dropdow_field.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:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart';
class BranchesFilterView extends StatefulWidget { class BranchesFilterView extends StatefulWidget {
const BranchesFilterView({super.key}); const BranchesFilterView({super.key});
@ -45,7 +47,7 @@ class _BranchesFilterViewState extends State<BranchesFilterView> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: CustomAppBar( appBar: CustomAppBar(
title: "Branches Filter", title: LocaleKeys.branchesFilter.tr(),
profileImageUrl: MyAssets.bnCar, profileImageUrl: MyAssets.bnCar,
isRemoveBackButton: false, isRemoveBackButton: false,
isDrawerEnabled: false, isDrawerEnabled: false,
@ -55,7 +57,8 @@ class _BranchesFilterViewState extends State<BranchesFilterView> {
}, },
), ),
body: Consumer<AppointmentsVM>( body: Consumer<AppointmentsVM>(
builder: (BuildContext context, AppointmentsVM appointmentsVM, Widget? child) { builder: (BuildContext context, AppointmentsVM appointmentsVM,
Widget? child) {
return WillPopScope( return WillPopScope(
onWillPop: () async { onWillPop: () async {
context.read<AdVM>().resetValues(); context.read<AdVM>().resetValues();
@ -67,31 +70,55 @@ class _BranchesFilterViewState extends State<BranchesFilterView> {
children: [ children: [
20.height, 20.height,
SearchEntityWidget( SearchEntityWidget(
title: "Search By Provider", title: LocaleKeys.searchByProvider.tr(),
actionWidget: Builder( actionWidget: Builder(
builder: (context) { builder: (context) {
return DropdownField( return DropdownField(
(DropValue value) => appointmentsVM.updateBranchFilterSelectedProviderId(SelectionModel(selectedId: value.id, selectedOption: value.value), isForSearch: true), (DropValue value) => appointmentsVM
.updateBranchFilterSelectedProviderId(
SelectionModel(
selectedId: value.id,
selectedOption: value.value),
isForSearch: true),
list: appointmentsVM.providersDropList, list: appointmentsVM.providersDropList,
dropdownValue: appointmentsVM.branchFilterSelectedProviderId.selectedId != -1 dropdownValue: appointmentsVM
? DropValue(appointmentsVM.branchFilterSelectedProviderId.selectedId, appointmentsVM.branchFilterSelectedProviderId.selectedOption, "") .branchFilterSelectedProviderId
.selectedId !=
-1
? DropValue(
appointmentsVM
.branchFilterSelectedProviderId
.selectedId,
appointmentsVM
.branchFilterSelectedProviderId
.selectedOption,
"")
: null, : null,
hint: "Select Provider", hint: LocaleKeys.selectProvider.tr(),
); );
}, },
), ),
historyContent: appointmentsVM.branchFilterProviderSearchHistory, historyContent:
appointmentsVM.branchFilterProviderSearchHistory,
onHistoryItemDeleted: (index) { onHistoryItemDeleted: (index) {
appointmentsVM.removeBranchFilterProviderSearchHistory(index: index); appointmentsVM.removeBranchFilterProviderSearchHistory(
index: index);
}, },
onHistoryItemTapped: (DropValue value) => onHistoryItemTapped: (DropValue value) =>
appointmentsVM.updateBranchFilterSelectedProviderId(SelectionModel(selectedId: value.id, selectedOption: value.value), isForSearch: true), appointmentsVM.updateBranchFilterSelectedProviderId(
SelectionModel(
selectedId: value.id,
selectedOption: value.value),
isForSearch: true),
), ),
const Divider(thickness: 1.2).paddingOnly(top: 5, bottom: 5), const Divider(thickness: 1.2)
.paddingOnly(top: 5, bottom: 5),
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
"Search By Distance".toText(fontSize: 16, isBold: true), LocaleKeys.searchByDistance
.tr()
.toText(fontSize: 16, isBold: true),
Row( Row(
children: [ children: [
"0 KM".toText(fontSize: 12, isBold: true), "0 KM".toText(fontSize: 12, isBold: true),
@ -99,59 +126,104 @@ class _BranchesFilterViewState extends State<BranchesFilterView> {
child: SliderWidget( child: SliderWidget(
minValue: 0, minValue: 0,
maxValue: 100, maxValue: 100,
value: appointmentsVM.branchFilterCurrentDistance, value:
onChanged: appointmentsVM.updateBranchFilterCurrentDistance, appointmentsVM.branchFilterCurrentDistance,
onChanged: appointmentsVM
.updateBranchFilterCurrentDistance,
), ),
), ),
"${appointmentsVM.branchFilterCurrentDistance.toInt()} KM".toText(fontSize: 12, isBold: true), "${appointmentsVM.branchFilterCurrentDistance.toInt()} KM"
.toText(fontSize: 12, isBold: true),
], ],
), ),
], ],
), ),
const Divider(thickness: 1.2).paddingOnly(top: 5, bottom: 5), const Divider(thickness: 1.2)
.paddingOnly(top: 5, bottom: 5),
SearchEntityWidget( SearchEntityWidget(
title: "Search By Category", title: LocaleKeys.searchByCategory.tr(),
actionWidget: Builder( actionWidget: Builder(
builder: (context) { builder: (context) {
return DropdownField( return DropdownField(
(DropValue value) => appointmentsVM.updateBranchFilterSelectedCategoryId(SelectionModel(selectedId: value.id, selectedOption: value.value), isForSearch: true), (DropValue value) => appointmentsVM
.updateBranchFilterSelectedCategoryId(
SelectionModel(
selectedId: value.id,
selectedOption: value.value),
isForSearch: true),
list: appointmentsVM.categoryDropList, list: appointmentsVM.categoryDropList,
dropdownValue: appointmentsVM.branchFilterSelectedCategoryId.selectedId != -1 dropdownValue: appointmentsVM
? DropValue(appointmentsVM.branchFilterSelectedCategoryId.selectedId, appointmentsVM.branchFilterSelectedCategoryId.selectedOption, "") .branchFilterSelectedCategoryId
.selectedId !=
-1
? DropValue(
appointmentsVM
.branchFilterSelectedCategoryId
.selectedId,
appointmentsVM
.branchFilterSelectedCategoryId
.selectedOption,
"")
: null, : null,
hint: "Select Category", hint: LocaleKeys.selectCategory.tr(),
); );
}, },
), ),
historyContent: appointmentsVM.branchFilterCategorySearchHistory, historyContent:
appointmentsVM.branchFilterCategorySearchHistory,
onHistoryItemDeleted: (index) { onHistoryItemDeleted: (index) {
appointmentsVM.removeBranchFilterCategorySearchHistory(index: index); appointmentsVM.removeBranchFilterCategorySearchHistory(
index: index);
}, },
onHistoryItemTapped: (DropValue value) => onHistoryItemTapped: (DropValue value) =>
appointmentsVM.updateBranchFilterSelectedCategoryId(SelectionModel(selectedId: value.id, selectedOption: value.value), isForSearch: true), appointmentsVM.updateBranchFilterSelectedCategoryId(
SelectionModel(
selectedId: value.id,
selectedOption: value.value),
isForSearch: true),
), ),
const Divider(thickness: 1.2).paddingOnly(top: 5, bottom: 5), const Divider(thickness: 1.2)
.paddingOnly(top: 5, bottom: 5),
SearchEntityWidget( SearchEntityWidget(
title: "Search By Service", title: LocaleKeys.searchByService.tr(),
actionWidget: Builder(builder: (context) { actionWidget: Builder(builder: (context) {
return DropdownField( return DropdownField(
(DropValue value) => appointmentsVM.updateBranchFilterSelectedServiceId(SelectionModel(selectedId: value.id, selectedOption: value.value), isForSearch: true), (DropValue value) => appointmentsVM
.updateBranchFilterSelectedServiceId(
SelectionModel(
selectedId: value.id,
selectedOption: value.value),
isForSearch: true),
list: appointmentsVM.servicesDropList, list: appointmentsVM.servicesDropList,
dropdownValue: appointmentsVM.branchFilterSelectedServiceId.selectedId != -1 dropdownValue: appointmentsVM
? DropValue(appointmentsVM.branchFilterSelectedServiceId.selectedId, appointmentsVM.branchFilterSelectedServiceId.selectedOption, "") .branchFilterSelectedServiceId
.selectedId !=
-1
? DropValue(
appointmentsVM
.branchFilterSelectedServiceId.selectedId,
appointmentsVM.branchFilterSelectedServiceId
.selectedOption,
"")
: null, : null,
hint: "Select Services", hint: LocaleKeys.selectService.tr(),
); );
}), }),
historyContent: appointmentsVM.branchFilterServicesSearchHistory, historyContent:
onHistoryItemDeleted: (index) => appointmentsVM.removeBranchFilterServicesSearchHistory(index: index), appointmentsVM.branchFilterServicesSearchHistory,
onHistoryItemDeleted: (index) => appointmentsVM
.removeBranchFilterServicesSearchHistory(
index: index),
onHistoryItemTapped: (DropValue value) => null, onHistoryItemTapped: (DropValue value) => null,
), ),
const Divider(thickness: 1.2).paddingOnly(top: 5, bottom: 5), const Divider(thickness: 1.2)
.paddingOnly(top: 5, bottom: 5),
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
"Search By Minimum Ratings".toText(fontSize: 16, isBold: true), LocaleKeys.searchByMinimumRatings
.tr()
.toText(fontSize: 16, isBold: true),
Row( Row(
children: [ children: [
"1 Star".toText(fontSize: 12, isBold: true), "1 Star".toText(fontSize: 12, isBold: true),
@ -160,10 +232,12 @@ class _BranchesFilterViewState extends State<BranchesFilterView> {
minValue: 0, minValue: 0,
maxValue: 5, maxValue: 5,
value: appointmentsVM.branchFilterByRating, value: appointmentsVM.branchFilterByRating,
onChanged: appointmentsVM.updateBranchFilterByRating, onChanged:
appointmentsVM.updateBranchFilterByRating,
), ),
), ),
"${appointmentsVM.branchFilterByRating.toInt()} Star".toText(fontSize: 12, isBold: true), "${appointmentsVM.branchFilterByRating.toInt()} Star"
.toText(fontSize: 12, isBold: true),
], ],
), ),
], ],
@ -180,7 +254,7 @@ class _BranchesFilterViewState extends State<BranchesFilterView> {
Expanded( Expanded(
child: ShowFillButton( child: ShowFillButton(
maxHeight: 55, maxHeight: 55,
title: "Search", title: LocaleKeys.search.tr(),
onPressed: () { onPressed: () {
Navigator.pop(context); Navigator.pop(context);
appointmentsVM.getBranchesBasedOnFilters(); appointmentsVM.getBranchesBasedOnFilters();
@ -195,11 +269,11 @@ class _BranchesFilterViewState extends State<BranchesFilterView> {
8.height, 8.height,
InkWell( InkWell(
onTap: () => appointmentsVM.clearBranchFilters(), onTap: () => appointmentsVM.clearBranchFilters(),
child: "Clear Filters".toText( child: LocaleKeys.clearFilters.tr().toText(
fontSize: 14, fontSize: 14,
isBold: true, isBold: true,
color: MyColors.darkPrimaryColor, color: MyColors.darkPrimaryColor,
), ),
), ),
10.height, 10.height,
], ],

@ -6,6 +6,7 @@ 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/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/models/chat_models/chat_message_model.dart'; import 'package:mc_common_app/models/chat_models/chat_message_model.dart';
import 'package:mc_common_app/models/requests_models/request_model.dart'; import 'package:mc_common_app/models/requests_models/request_model.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
@ -19,6 +20,7 @@ import 'package:mc_common_app/widgets/common_widgets/info_bottom_sheet.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:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart' as lcl;
class ChatView extends StatelessWidget { class ChatView extends StatelessWidget {
final ChatViewArguments chatViewArguments; final ChatViewArguments chatViewArguments;
@ -32,11 +34,15 @@ class ChatView extends StatelessWidget {
isScrollControlled: true, isScrollControlled: true,
enableDrag: true, enableDrag: true,
builder: (BuildContext context) { builder: (BuildContext context) {
return Consumer(builder: (BuildContext context, RequestsVM requestsVM, Widget? child) { return Consumer(builder:
(BuildContext context, RequestsVM requestsVM, Widget? child) {
return InfoBottomSheet( return InfoBottomSheet(
title: "Make an offer".toText(fontSize: 28, isBold: true, letterSpacing: -1.44), title: LocaleKeys.makeAnOffer
.tr()
.toText(fontSize: 28, isBold: true, letterSpacing: -1.44),
description: Padding( description: Padding(
padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -48,7 +54,7 @@ class ChatView extends StatelessWidget {
value: requestsVM.offerPrice, value: requestsVM.offerPrice,
errorValue: requestsVM.offerPriceError, errorValue: requestsVM.offerPriceError,
keyboardType: TextInputType.number, keyboardType: TextInputType.number,
hint: "Enter amount", hint: LocaleKeys.enterAmount.tr(),
onChanged: (v) => requestsVM.updateOfferPrice(v), onChanged: (v) => requestsVM.updateOfferPrice(v),
), ),
12.height, 12.height,
@ -57,14 +63,15 @@ class ChatView extends StatelessWidget {
value: requestsVM.offerDescription, value: requestsVM.offerDescription,
errorValue: requestsVM.offerDescriptionError, errorValue: requestsVM.offerDescriptionError,
keyboardType: TextInputType.text, keyboardType: TextInputType.text,
hint: "Description", hint: LocaleKeys.description.tr(),
onChanged: (v) => requestsVM.updateOfferDescription(v), onChanged: (v) =>
requestsVM.updateOfferDescription(v),
), ),
], ],
), ),
25.height, 25.height,
ShowFillButton( ShowFillButton(
title: "Submit", title: LocaleKeys.submit.tr(),
onPressed: () { onPressed: () {
requestsVM.onSendOfferPressed( requestsVM.onSendOfferPressed(
context: context, context: context,
@ -91,22 +98,30 @@ class ChatView extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: const CustomAppBar(title: "Chat"), appBar: CustomAppBar(title: LocaleKeys.chat.tr()),
body: Consumer2<ChatVM, RequestsVM>(builder: (BuildContext context, ChatVM chatVM, RequestsVM requestVM, Widget? child) { body: Consumer2<ChatVM, RequestsVM>(builder: (BuildContext context,
ChatVM chatVM, RequestsVM requestVM, Widget? child) {
final chatMessages = AppState().currentAppType == AppType.customer final chatMessages = AppState().currentAppType == AppType.customer
? chatVM.serviceProviderOffersList[chatViewArguments.providerIndex].chatMessages ? chatVM.serviceProviderOffersList[chatViewArguments.providerIndex]
: requestVM.myFilteredRequests[chatViewArguments.requestIndex].chatMessages; .chatMessages
: requestVM.myFilteredRequests[chatViewArguments.requestIndex]
.chatMessages;
return chatMessages == null return chatMessages == null
? Center(child: "No Requests to show.".toText(fontSize: 16, color: MyColors.lightTextColor)) ? Center(
child: LocaleKeys.noRequestsShow
.tr()
.toText(fontSize: 16, color: MyColors.lightTextColor))
: Column( : Column(
children: [ children: [
Expanded( Expanded(
child: ListView.separated( child: ListView.separated(
itemCount: chatMessages.length, itemCount: chatMessages.length,
separatorBuilder: (BuildContext context, int index) => 20.height, separatorBuilder: (BuildContext context, int index) =>
20.height,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
ChatMessageModel chatMessageModel = chatMessages[index]; ChatMessageModel chatMessageModel = chatMessages[index];
return ChatMessageCustomWidget(chatMessageModel: chatMessageModel); return ChatMessageCustomWidget(
chatMessageModel: chatMessageModel);
}, },
).horPaddingMain(), ).horPaddingMain(),
), ),
@ -132,7 +147,7 @@ class ChatView extends StatelessWidget {
flex: 8, flex: 8,
child: TxtField( child: TxtField(
value: chatVM.chatMessageText, value: chatVM.chatMessageText,
hint: "Type your message here..", hint: LocaleKeys.typeMessageHere.tr(),
keyboardType: TextInputType.text, keyboardType: TextInputType.text,
isNeedBorder: false, isNeedBorder: false,
onChanged: (v) => chatVM.updateChatMessageText(v), onChanged: (v) => chatVM.updateChatMessageText(v),
@ -178,7 +193,8 @@ class ChatMessageCustomWidget extends StatefulWidget {
const ChatMessageCustomWidget({super.key, required this.chatMessageModel}); const ChatMessageCustomWidget({super.key, required this.chatMessageModel});
@override @override
State<ChatMessageCustomWidget> createState() => _ChatMessageCustomWidgetState(); State<ChatMessageCustomWidget> createState() =>
_ChatMessageCustomWidgetState();
} }
class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> { class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
@ -188,11 +204,15 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
isScrollControlled: true, isScrollControlled: true,
enableDrag: true, enableDrag: true,
builder: (BuildContext context) { builder: (BuildContext context) {
return Consumer(builder: (BuildContext context, ChatVM chatVM, Widget? child) { return Consumer(
builder: (BuildContext context, ChatVM chatVM, Widget? child) {
return InfoBottomSheet( return InfoBottomSheet(
title: "Make an offer".toText(fontSize: 28, isBold: true, letterSpacing: -1.44), title: LocaleKeys.makeAnOffer
.tr()
.toText(fontSize: 28, isBold: true, letterSpacing: -1.44),
description: Padding( description: Padding(
padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -203,14 +223,18 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
ListView.separated( ListView.separated(
shrinkWrap: true, shrinkWrap: true,
itemCount: chatVM.offerRejectModelList.length, itemCount: chatVM.offerRejectModelList.length,
separatorBuilder: (BuildContext context, int index) => const Divider(thickness: 0.5), separatorBuilder: (BuildContext context, int index) =>
const Divider(thickness: 0.5),
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
OfferRequestCommentModel offerRequestCommentModel = chatVM.offerRejectModelList[index]; OfferRequestCommentModel offerRequestCommentModel =
chatVM.offerRejectModelList[index];
return CircleCheckBoxWithTitle( return CircleCheckBoxWithTitle(
isChecked: offerRequestCommentModel.isSelected ?? false, isChecked:
offerRequestCommentModel.isSelected ?? false,
title: '${offerRequestCommentModel.title}', title: '${offerRequestCommentModel.title}',
onSelected: () { onSelected: () {
chatVM.updateSelectionInOfferRejectModelList(index); chatVM.updateSelectionInOfferRejectModelList(
index);
}, },
selectedColor: MyColors.darkPrimaryColor, selectedColor: MyColors.darkPrimaryColor,
); );
@ -222,14 +246,15 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
value: chatVM.rejectOfferDescription, value: chatVM.rejectOfferDescription,
errorValue: chatVM.rejectOfferDescriptionError, errorValue: chatVM.rejectOfferDescriptionError,
keyboardType: TextInputType.text, keyboardType: TextInputType.text,
hint: "Description", hint: LocaleKeys.description.tr(),
onChanged: (v) => chatVM.updateRejectOfferDescription(v), onChanged: (v) =>
chatVM.updateRejectOfferDescription(v),
), ),
], ],
), ),
25.height, 25.height,
ShowFillButton( ShowFillButton(
title: "Submit", title: LocaleKeys.submit.tr(),
onPressed: () {}, onPressed: () {},
maxWidth: double.infinity, maxWidth: double.infinity,
), ),
@ -242,8 +267,12 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
); );
} }
Widget buildOfferDetailsInChatMessage({required ChatMessageModel chatMessageModel, required BuildContext context}) { Widget buildOfferDetailsInChatMessage(
final requestOfferStatusEnum = chatMessageModel.reqOffer!.requestOfferStatusEnum ?? RequestOfferStatusEnum.offer; {required ChatMessageModel chatMessageModel,
required BuildContext context}) {
final requestOfferStatusEnum =
chatMessageModel.reqOffer!.requestOfferStatusEnum ??
RequestOfferStatusEnum.offer;
switch (requestOfferStatusEnum) { switch (requestOfferStatusEnum) {
case RequestOfferStatusEnum.offer: case RequestOfferStatusEnum.offer:
@ -253,9 +282,18 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
Row( Row(
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
"${chatMessageModel.reqOffer!.price}".toText(fontSize: 19, isBold: true, color: AppState().currentAppType == AppType.provider ? MyColors.white : MyColors.darkTextColor), "${chatMessageModel.reqOffer!.price}".toText(
fontSize: 19,
isBold: true,
color: AppState().currentAppType == AppType.provider
? MyColors.white
: MyColors.darkTextColor),
5.width, 5.width,
"SAR".toText(color: MyColors.lightTextColor, height: 2.2, fontSize: 10, isBold: true), LocaleKeys.sar.tr().toText(
color: MyColors.lightTextColor,
height: 2.2,
fontSize: 10,
isBold: true),
], ],
), ),
if (widget.chatMessageModel.isMyMessage == false) ...[ if (widget.chatMessageModel.isMyMessage == false) ...[
@ -265,21 +303,24 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
Expanded( Expanded(
child: ShowFillButton( child: ShowFillButton(
maxHeight: 27, maxHeight: 27,
title: "Accept", title: LocaleKeys.accept.tr(),
fontSize: 9, fontSize: 9,
borderColor: MyColors.greenColor, borderColor: MyColors.greenColor,
isFilled: false, isFilled: false,
onPressed: () async { onPressed: () async {
int status = await context.read<ChatVM>().onActionOfferTapped( int status =
context: context, await context.read<ChatVM>().onActionOfferTapped(
requestOfferStatusEnum: RequestOfferStatusEnum.accepted, context: context,
reqOfferId: chatMessageModel.reqOfferID ?? -1, requestOfferStatusEnum:
); RequestOfferStatusEnum.accepted,
reqOfferId: chatMessageModel.reqOfferID ?? -1,
);
if (status != -1) { if (status != -1) {
log("accepted: $status"); log("accepted: $status");
if (chatMessageModel.reqOfferID == status) { if (chatMessageModel.reqOfferID == status) {
chatMessageModel.reqOffer!.requestOfferStatusEnum = RequestOfferStatusEnum.accepted; chatMessageModel.reqOffer!.requestOfferStatusEnum =
RequestOfferStatusEnum.accepted;
setState(() {}); setState(() {});
} }
} }
@ -292,7 +333,7 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
Expanded( Expanded(
child: ShowFillButton( child: ShowFillButton(
maxHeight: 27, maxHeight: 27,
title: "Reject", title: LocaleKeys.reject.tr(),
borderColor: MyColors.redColor, borderColor: MyColors.redColor,
isFilled: false, isFilled: false,
backgroundColor: MyColors.white, backgroundColor: MyColors.white,
@ -312,48 +353,64 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
return Column( return Column(
children: [ children: [
Center( Center(
child: "New Offer Required.".toText( child: LocaleKeys.newOfferRequired.tr().toText(
color: MyColors.adPendingStatusColor, color: MyColors.adPendingStatusColor,
fontSize: 12, fontSize: 12,
isItalic: true, isItalic: true,
), ),
).toContainer(borderRadius: 40, width: double.infinity, backgroundColor: MyColors.adPendingStatusColor.withOpacity(0.16)), ).toContainer(
borderRadius: 40,
width: double.infinity,
backgroundColor:
MyColors.adPendingStatusColor.withOpacity(0.16)),
], ],
); );
case RequestOfferStatusEnum.accepted: case RequestOfferStatusEnum.accepted:
return Column( return Column(
children: [ children: [
Center( Center(
child: "Offer has been accepted.".toText( child: LocaleKeys.offerHasBeenAccepted.tr().toText(
color: MyColors.adPendingStatusColor, color: MyColors.adPendingStatusColor,
fontSize: 12, fontSize: 12,
isItalic: true, isItalic: true,
), ),
).toContainer(borderRadius: 40, width: double.infinity, backgroundColor: MyColors.adPendingStatusColor.withOpacity(0.16)), ).toContainer(
borderRadius: 40,
width: double.infinity,
backgroundColor:
MyColors.adPendingStatusColor.withOpacity(0.16)),
], ],
); );
case RequestOfferStatusEnum.rejected: case RequestOfferStatusEnum.rejected:
return Column( return Column(
children: [ children: [
Center( Center(
child: "Offer has been rejected.".toText( child: LocaleKeys.offerHasBeenRejected.tr().toText(
color: MyColors.adPendingStatusColor, color: MyColors.adPendingStatusColor,
fontSize: 12, fontSize: 12,
isItalic: true, isItalic: true,
), ),
).toContainer(borderRadius: 40, width: double.infinity, backgroundColor: MyColors.adPendingStatusColor.withOpacity(0.16)), ).toContainer(
borderRadius: 40,
width: double.infinity,
backgroundColor:
MyColors.adPendingStatusColor.withOpacity(0.16)),
], ],
); );
case RequestOfferStatusEnum.cancel: case RequestOfferStatusEnum.cancel:
return Column( return Column(
children: [ children: [
Center( Center(
child: "Offer has been cancelled.".toText( child: LocaleKeys.offerHasBeenCancelled.tr().toText(
color: MyColors.adPendingStatusColor, color: MyColors.adPendingStatusColor,
fontSize: 12, fontSize: 12,
isItalic: true, isItalic: true,
), ),
).toContainer(borderRadius: 40, width: double.infinity, backgroundColor: MyColors.adPendingStatusColor.withOpacity(0.16)), ).toContainer(
borderRadius: 40,
width: double.infinity,
backgroundColor:
MyColors.adPendingStatusColor.withOpacity(0.16)),
], ],
); );
} }
@ -362,7 +419,9 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Directionality( return Directionality(
textDirection: (widget.chatMessageModel.isMyMessage ?? false) ? TextDirection.rtl : TextDirection.ltr, textDirection: (widget.chatMessageModel.isMyMessage ?? false)
? TextDirection.rtl
: TextDirection.ltr,
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -384,7 +443,10 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
((widget.chatMessageModel.isMyMessage ?? false) ? "You" : widget.chatMessageModel.senderName ?? "").toText(fontSize: 16, isBold: true), ((widget.chatMessageModel.isMyMessage ?? false)
? "You"
: widget.chatMessageModel.senderName ?? "")
.toText(fontSize: 16, isBold: true),
], ],
), ),
5.height, 5.height,
@ -396,8 +458,12 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
Expanded( Expanded(
child: Directionality( child: Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
child: (widget.chatMessageModel.chatText ?? "").toText( child:
color: (widget.chatMessageModel.isMyMessage ?? false) ? MyColors.white : MyColors.lightTextColor, (widget.chatMessageModel.chatText ?? "").toText(
color:
(widget.chatMessageModel.isMyMessage ?? false)
? MyColors.white
: MyColors.lightTextColor,
fontSize: 12, fontSize: 12,
// isBold: true, // isBold: true,
@ -406,15 +472,26 @@ class _ChatMessageCustomWidgetState extends State<ChatMessageCustomWidget> {
), ),
], ],
), ),
if (widget.chatMessageModel.chatMessageTypeEnum == ChatMessageTypeEnum.offer) ...[ if (widget.chatMessageModel.chatMessageTypeEnum ==
buildOfferDetailsInChatMessage(chatMessageModel: widget.chatMessageModel, context: context), ChatMessageTypeEnum.offer) ...[
buildOfferDetailsInChatMessage(
chatMessageModel: widget.chatMessageModel,
context: context),
], ],
], ],
).toContainer( ).toContainer(
isShadowEnabled: !(widget.chatMessageModel.isMyMessage ?? false), isShadowEnabled:
backgroundColor: (widget.chatMessageModel.isMyMessage ?? false) ? MyColors.darkIconColor : MyColors.white, !(widget.chatMessageModel.isMyMessage ?? false),
backgroundColor:
(widget.chatMessageModel.isMyMessage ?? false)
? MyColors.darkIconColor
: MyColors.white,
borderRadius: 0, borderRadius: 0,
margin: EdgeInsets.fromLTRB((widget.chatMessageModel.isMyMessage ?? false) ? 25 : 0, 0, !(widget.chatMessageModel.isMyMessage ?? false) ? 25 : 0, 0), margin: EdgeInsets.fromLTRB(
(widget.chatMessageModel.isMyMessage ?? false) ? 25 : 0,
0,
!(widget.chatMessageModel.isMyMessage ?? false) ? 25 : 0,
0),
), ),
], ],
), ),

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/classes/consts.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/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/utils.dart'; import 'package:mc_common_app/utils/utils.dart';
@ -9,6 +10,7 @@ import 'package:mc_common_app/view_models/payment_view_model.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:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart';
class PaymentMethodsView extends StatelessWidget { class PaymentMethodsView extends StatelessWidget {
final PaymentTypes paymentType; final PaymentTypes paymentType;
@ -22,7 +24,7 @@ class PaymentMethodsView extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: CustomAppBar( appBar: CustomAppBar(
title: "Payment Method", title: LocaleKeys.paymentMethod.tr(),
profileImageUrl: MyAssets.bnCar, profileImageUrl: MyAssets.bnCar,
isRemoveBackButton: false, isRemoveBackButton: false,
isDrawerEnabled: false, isDrawerEnabled: false,
@ -34,33 +36,46 @@ class PaymentMethodsView extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
20.height, 20.height,
"Select Payment Method".toText(fontSize: 18, isBold: true), LocaleKeys.selectPaymentMethod
.tr()
.toText(fontSize: 18, isBold: true),
15.height, 15.height,
Consumer( Consumer(
builder: (BuildContext context, PaymentVM paymentVm, Widget? child) { builder:
(BuildContext context, PaymentVM paymentVm, Widget? child) {
return Expanded( return Expanded(
child: ListView( child: ListView(
shrinkWrap: true, shrinkWrap: true,
children: [ children: [
PaymentMethodContainer( PaymentMethodContainer(
isSelected: paymentVm.selectedPaymentMethod == PaymentMethods.mada, isSelected: paymentVm.selectedPaymentMethod ==
onTap: () => paymentVm.updateSelectedPaymentMethod(PaymentMethods.mada), PaymentMethods.mada,
onTap: () => paymentVm
.updateSelectedPaymentMethod(PaymentMethods.mada),
cardAsset: MyAssets.madaPng), cardAsset: MyAssets.madaPng),
PaymentMethodContainer( PaymentMethodContainer(
isSelected: paymentVm.selectedPaymentMethod == PaymentMethods.visa, isSelected: paymentVm.selectedPaymentMethod ==
onTap: () => paymentVm.updateSelectedPaymentMethod(PaymentMethods.visa), PaymentMethods.visa,
onTap: () => paymentVm
.updateSelectedPaymentMethod(PaymentMethods.visa),
cardAsset: MyAssets.visaPng), cardAsset: MyAssets.visaPng),
PaymentMethodContainer( PaymentMethodContainer(
isSelected: paymentVm.selectedPaymentMethod == PaymentMethods.applePay, isSelected: paymentVm.selectedPaymentMethod ==
onTap: () => paymentVm.updateSelectedPaymentMethod(PaymentMethods.applePay), PaymentMethods.applePay,
onTap: () => paymentVm.updateSelectedPaymentMethod(
PaymentMethods.applePay),
cardAsset: MyAssets.applePayPng), cardAsset: MyAssets.applePayPng),
PaymentMethodContainer( PaymentMethodContainer(
isSelected: paymentVm.selectedPaymentMethod == PaymentMethods.masterCard, isSelected: paymentVm.selectedPaymentMethod ==
onTap: () => paymentVm.updateSelectedPaymentMethod(PaymentMethods.masterCard), PaymentMethods.masterCard,
onTap: () => paymentVm.updateSelectedPaymentMethod(
PaymentMethods.masterCard),
cardAsset: MyAssets.mastercardPng), cardAsset: MyAssets.mastercardPng),
PaymentMethodContainer( PaymentMethodContainer(
isSelected: paymentVm.selectedPaymentMethod == PaymentMethods.tamara, isSelected: paymentVm.selectedPaymentMethod ==
onTap: () => paymentVm.updateSelectedPaymentMethod(PaymentMethods.tamara), PaymentMethods.tamara,
onTap: () => paymentVm.updateSelectedPaymentMethod(
PaymentMethods.tamara),
cardAsset: MyAssets.tamaraEngPng), cardAsset: MyAssets.tamaraEngPng),
], ],
), ),
@ -71,7 +86,7 @@ class PaymentMethodsView extends StatelessWidget {
width: double.infinity, width: double.infinity,
child: ShowFillButton( child: ShowFillButton(
maxHeight: 55, maxHeight: 55,
title: "Continue", title: LocaleKeys.continu.tr(),
onPressed: () async { onPressed: () async {
bool isNeedToCallPayment = true; bool isNeedToCallPayment = true;
if (onTempContinue != null) { if (onTempContinue != null) {
@ -99,7 +114,12 @@ class PaymentMethodContainer extends StatelessWidget {
final String cardAsset; final String cardAsset;
final Function() onTap; final Function() onTap;
const PaymentMethodContainer({Key? key, required this.isSelected, required this.cardAsset, required this.onTap}) : super(key: key); const PaymentMethodContainer(
{Key? key,
required this.isSelected,
required this.cardAsset,
required this.onTap})
: super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -112,7 +132,9 @@ class PaymentMethodContainer extends StatelessWidget {
decoration: BoxDecoration( decoration: BoxDecoration(
color: MyColors.white, color: MyColors.white,
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.circular(10),
border: Border.all(color: isSelected ? Colors.green : Colors.transparent, width: isSelected ? 2.0 : 0.0), border: Border.all(
color: isSelected ? Colors.green : Colors.transparent,
width: isSelected ? 2.0 : 0.0),
), ),
child: Padding( child: Padding(
padding: const EdgeInsets.all(12), padding: const EdgeInsets.all(12),
@ -121,7 +143,11 @@ class PaymentMethodContainer extends StatelessWidget {
Container( Container(
width: 24, width: 24,
height: 24, height: 24,
decoration: Utils.containerColorRadiusBorderWidth(isSelected ? MyColors.primaryColor : Colors.transparent, 100, Colors.grey, 0.5), decoration: Utils.containerColorRadiusBorderWidth(
isSelected ? MyColors.primaryColor : Colors.transparent,
100,
Colors.grey,
0.5),
), ),
12.width, 12.width,
Container( Container(
@ -131,7 +157,12 @@ class PaymentMethodContainer extends StatelessWidget {
child: Image.asset(cardAsset), child: Image.asset(cardAsset),
), ),
Utils.mFlex(1), Utils.mFlex(1),
isSelected ? Utils.statusContainerChip(text: "Selected", padding: EdgeInsets.symmetric(vertical: 6, horizontal: 10)) : SizedBox(), isSelected
? Utils.statusContainerChip(
text: "Selected",
padding:
EdgeInsets.symmetric(vertical: 6, horizontal: 10))
: SizedBox(),
], ],
), ),
), ),

@ -9,6 +9,7 @@ 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/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/theme/colors.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/app_permission_handler.dart';
import 'package:mc_common_app/view_models/service_view_model.dart'; import 'package:mc_common_app/view_models/service_view_model.dart';
@ -19,6 +20,7 @@ import 'package:mc_common_app/views/user/change_password_page.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart';
class ProfileScreen extends StatefulWidget { class ProfileScreen extends StatefulWidget {
const ProfileScreen({Key? key}) : super(key: key); const ProfileScreen({Key? key}) : super(key: key);
@ -52,15 +54,29 @@ class _ProfileScreenState extends State<ProfileScreen> {
flex: 3, flex: 3,
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
image: AppState().getUser.data!.userInfo!.userLocalImage != null image: AppState()
.getUser
.data!
.userInfo!
.userLocalImage !=
null
? DecorationImage( ? DecorationImage(
image: FileImage(AppState().getUser.data!.userInfo!.userLocalImage!), image: FileImage(AppState()
.getUser
.data!
.userInfo!
.userLocalImage!),
fit: BoxFit.cover, fit: BoxFit.cover,
) )
: AppState().getUser.data!.userInfo!.userImageUrl != null : AppState().getUser.data!.userInfo!.userImageUrl !=
null
? DecorationImage( ? DecorationImage(
image: CachedNetworkImageProvider( image: CachedNetworkImageProvider(
AppState().getUser.data!.userInfo!.userImageUrl, AppState()
.getUser
.data!
.userInfo!
.userImageUrl,
), ),
fit: BoxFit.cover, fit: BoxFit.cover,
) )
@ -87,40 +103,52 @@ class _ProfileScreenState extends State<ProfileScreen> {
child: ListView( child: ListView(
children: [ children: [
20.height, 20.height,
"${AppState().getUser.data!.userInfo!.firstName} ${AppState().getUser.data!.userInfo!.lastName ?? ""}".toText(fontSize: 20).paddingOnly(left: 25), "${AppState().getUser.data!.userInfo!.firstName} ${AppState().getUser.data!.userInfo!.lastName ?? ""}"
.toText(fontSize: 20)
.paddingOnly(left: 25),
Column( Column(
children: [ children: [
CustomProfileOptionsTile( CustomProfileOptionsTile(
titleText: "Country", titleText: LocaleKeys.country.tr(),
subtitleText: "Saudi Arabia", subtitleText: "Saudi Arabia",
needBorderBelow: true, needBorderBelow: true,
onTap: () {}, onTap: () {},
), ),
CustomProfileOptionsTile( CustomProfileOptionsTile(
titleText: "Email", titleText: LocaleKeys.email.tr(),
subtitleText: "${AppState().getUser.data!.userInfo!.email}", subtitleText:
"${AppState().getUser.data!.userInfo!.email}",
needBorderBelow: true, needBorderBelow: true,
onTap: () { onTap: () {
Navigator.pushNamed(context, AppRoutes.changeEmailPage); Navigator.pushNamed(
context, AppRoutes.changeEmailPage);
}, },
), ),
CustomProfileOptionsTile( CustomProfileOptionsTile(
titleText: "Phone Number", titleText: LocaleKeys.phoneNumber.tr(),
subtitleText: "${AppState().getUser.data!.userInfo!.email}", subtitleText:
"${AppState().getUser.data!.userInfo!.email}",
needBorderBelow: true, needBorderBelow: true,
onTap: () { onTap: () {
Navigator.pushNamed(context, AppRoutes.changeMobilePage); Navigator.pushNamed(
context, AppRoutes.changeMobilePage);
}, },
), ),
CustomProfileOptionsTile( CustomProfileOptionsTile(
titleText: "Password", titleText: LocaleKeys.password.tr(),
subtitleText: "************", subtitleText: "************",
onTap: () { onTap: () {
Navigator.pushNamed(context, AppRoutes.changePassword); Navigator.pushNamed(
context, AppRoutes.changePassword);
}, },
), ),
], ],
).toContainer(width: double.infinity, isShadowEnabled: true, paddingAll: 10, margin: const EdgeInsets.fromLTRB(24, 20, 24, 0), borderRadius: 0), ).toContainer(
width: double.infinity,
isShadowEnabled: true,
paddingAll: 10,
margin: const EdgeInsets.fromLTRB(24, 20, 24, 0),
borderRadius: 0),
], ],
), ),
), ),
@ -133,7 +161,8 @@ class _ProfileScreenState extends State<ProfileScreen> {
height: 90, height: 90,
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: ClipOval( child: ClipOval(
child: AppState().getUser.data!.userInfo!.userLocalImage != null child: AppState().getUser.data!.userInfo!.userLocalImage !=
null
? Image.file( ? Image.file(
AppState().getUser.data!.userInfo!.userLocalImage!, AppState().getUser.data!.userInfo!.userLocalImage!,
width: 90, width: 90,
@ -141,7 +170,8 @@ class _ProfileScreenState extends State<ProfileScreen> {
fit: BoxFit.fill, fit: BoxFit.fill,
) )
: CachedNetworkImage( : CachedNetworkImage(
imageUrl: "${AppState().getUser.data!.userInfo!.userImageUrl}", imageUrl:
"${AppState().getUser.data!.userInfo!.userImageUrl}",
imageBuilder: (context, imageProvider) => Container( imageBuilder: (context, imageProvider) => Container(
decoration: BoxDecoration( decoration: BoxDecoration(
image: DecorationImage( image: DecorationImage(
@ -150,8 +180,10 @@ class _ProfileScreenState extends State<ProfileScreen> {
), ),
), ),
), ),
placeholder: (context, url) => const Center(child: CircularProgressIndicator()), placeholder: (context, url) =>
errorWidget: (context, url, error) => const Icon(Icons.error), const Center(child: CircularProgressIndicator()),
errorWidget: (context, url, error) =>
const Icon(Icons.error),
width: 90, width: 90,
height: 90, height: 90,
fit: BoxFit.fill, fit: BoxFit.fill,
@ -168,8 +200,14 @@ class _ProfileScreenState extends State<ProfileScreen> {
child: Container( child: Container(
height: 35, height: 35,
width: 35, width: 35,
decoration: BoxDecoration(color: MyColors.white, shape: BoxShape.circle, border: Border.all(color: MyColors.darkTextColor, width: 0.1)), decoration: BoxDecoration(
child: const Icon(Icons.edit_note, color: MyColors.darkIconColor, size: 27).paddingOnly(left: 5), 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( ).onPress(
() async { () async {
model.updateUserImage(context); model.updateUserImage(context);

@ -1,3 +1,4 @@
import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/view_models/requests_view_model.dart'; import 'package:mc_common_app/view_models/requests_view_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/classes/consts.dart';
@ -13,6 +14,7 @@ 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:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart';
class CreateRequestPage extends StatelessWidget { class CreateRequestPage extends StatelessWidget {
const CreateRequestPage({super.key}); const CreateRequestPage({super.key});
@ -20,8 +22,8 @@ class CreateRequestPage extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: const CustomAppBar( appBar: CustomAppBar(
title: "Create Request", title: LocaleKeys.createRequest.tr(),
), ),
body: Consumer<RequestsVM>(builder: (context, requestsVM, widget) { body: Consumer<RequestsVM>(builder: (context, requestsVM, widget) {
return Column( return Column(
@ -31,204 +33,323 @@ class CreateRequestPage extends StatelessWidget {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
"Vehicle Detail".toText(fontSize: 18, isBold: true), LocaleKeys.vehicleDetails
.tr()
.toText(fontSize: 18, isBold: true),
8.height, 8.height,
if (requestsVM.isFetchingRequestType) ...[ if (requestsVM.isFetchingRequestType) ...[
const Center( const Center(
child: CircularProgressIndicator(), child: CircularProgressIndicator(),
), ),
] else ] else ...[
...[ Builder(builder: (context) {
Builder(builder: (context) { List<DropValue> requestTypeDrop = [];
List<DropValue> requestTypeDrop = []; for (var element in requestsVM.myRequestsTypeEnum) {
for (var element in requestsVM.myRequestsTypeEnum) { requestTypeDrop.add(DropValue(
requestTypeDrop.add(DropValue(element.enumValue.toInt() ?? 0, element.enumValueStr ?? "", "")); element.enumValue.toInt() ?? 0,
} element.enumValueStr ?? "",
return DropdownField( ""));
(DropValue value) => requestsVM.updateSelectionRequestTypeId(SelectionModel(selectedId: value.id, selectedOption: value.value)), }
list: requestTypeDrop, return DropdownField(
dropdownValue: requestsVM.requestTypeId.selectedId != -1 ? DropValue(requestsVM.requestTypeId.selectedId, requestsVM.requestTypeId.selectedOption, "") : null, (DropValue value) => requestsVM
hint: "Request Type", .updateSelectionRequestTypeId(SelectionModel(
errorValue: requestsVM.requestTypeId.errorValue, selectedId: value.id,
); selectedOption: value.value)),
}), list: requestTypeDrop,
], dropdownValue:
requestsVM.requestTypeId.selectedId != -1
? DropValue(
requestsVM.requestTypeId.selectedId,
requestsVM.requestTypeId.selectedOption,
"")
: null,
hint: LocaleKeys.requestType.tr(),
errorValue: requestsVM.requestTypeId.errorValue,
);
}),
],
8.height, 8.height,
if (requestsVM.requestTypeId.selectedId != -1) if (requestsVM.requestTypeId.selectedId != -1)
if (requestsVM.isFetchingVehicleType) ...[ if (requestsVM.isFetchingVehicleType) ...[
const Center( const Center(
child: CircularProgressIndicator(), child: CircularProgressIndicator(),
), ),
] else ] else ...[
...[ Builder(builder: (context) {
Builder(builder: (context) { List<DropValue> vehicleTypeDrop = [];
List<DropValue> vehicleTypeDrop = []; for (var element in requestsVM.vehicleTypes) {
for (var element in requestsVM.vehicleTypes) { vehicleTypeDrop.add(DropValue(
vehicleTypeDrop.add(DropValue(element.id?.toInt() ?? 0, element.vehicleTypeName ?? "", "")); element.id?.toInt() ?? 0,
} element.vehicleTypeName ?? "",
return DropdownField( ""));
(DropValue value) => requestsVM.updateSelectionVehicleTypeId(SelectionModel(selectedId: value.id, selectedOption: value.value)), }
list: vehicleTypeDrop, return DropdownField(
dropdownValue: requestsVM.vehicleTypeId.selectedId != -1 ? DropValue(requestsVM.vehicleTypeId.selectedId, requestsVM.vehicleTypeId.selectedOption, "") : null, (DropValue value) => requestsVM
hint: "Vehicle Type", .updateSelectionVehicleTypeId(SelectionModel(
errorValue: requestsVM.vehicleTypeId.errorValue, selectedId: value.id,
); selectedOption: value.value)),
}), list: vehicleTypeDrop,
], dropdownValue:
requestsVM.vehicleTypeId.selectedId != -1
? DropValue(
requestsVM.vehicleTypeId.selectedId,
requestsVM.vehicleTypeId.selectedOption,
"")
: null,
hint: LocaleKeys.vehicleType.tr(),
errorValue: requestsVM.vehicleTypeId.errorValue,
);
}),
],
8.height, 8.height,
if (requestsVM.vehicleTypeId.selectedId != -1) if (requestsVM.vehicleTypeId.selectedId != -1)
if (requestsVM.isFetchingVehicleDetail) ...[ if (requestsVM.isFetchingVehicleDetail) ...[
const Center( const Center(
child: CircularProgressIndicator(), child: CircularProgressIndicator(),
), ),
] else ] else ...[
...[ Column(
Column( children: [
children: [ Builder(builder: (context) {
Builder(builder: (context) { List<DropValue> vehicleBrandsDrop = [];
List<DropValue> vehicleBrandsDrop = []; for (var element in requestsVM.vehicleBrands) {
for (var element in requestsVM.vehicleBrands) { vehicleBrandsDrop.add(DropValue(
vehicleBrandsDrop.add(DropValue(element.id?.toInt() ?? 0, element.vehicleBrandDescription ?? "", "")); element.id?.toInt() ?? 0,
} element.vehicleBrandDescription ?? "",
return DropdownField( ""));
(DropValue value) => requestsVM.updateSelectionVehicleBrandId(SelectionModel(selectedId: value.id, selectedOption: value.value)), }
list: vehicleBrandsDrop, return DropdownField(
dropdownValue: requestsVM.vehicleBrandId.selectedId != -1 ? DropValue(requestsVM.vehicleBrandId.selectedId, requestsVM.vehicleBrandId.selectedOption, "") : null, (DropValue value) =>
hint: "Brand", requestsVM.updateSelectionVehicleBrandId(
errorValue: requestsVM.vehicleBrandId.errorValue, SelectionModel(
); selectedId: value.id,
}), selectedOption: value.value)),
8.height, list: vehicleBrandsDrop,
Builder(builder: (context) { dropdownValue:
List<DropValue> vehicleModelsDrop = []; requestsVM.vehicleBrandId.selectedId != -1
for (var element in requestsVM.vehicleModels) { ? DropValue(
if (requestsVM.vehicleBrandId.selectedId == element.vehicleBrandID) vehicleModelsDrop.add(DropValue(element.id?.toInt() ?? 0, element.model ?? "", "")); requestsVM
} .vehicleBrandId.selectedId,
return DropdownField( requestsVM
(DropValue value) => requestsVM.updateSelectionVehicleModelId(SelectionModel(selectedId: value.id, selectedOption: value.value)), .vehicleBrandId.selectedOption,
list: vehicleModelsDrop, "")
dropdownValue: requestsVM.vehicleModelId.selectedId != -1 ? DropValue(requestsVM.vehicleModelId.selectedId, requestsVM.vehicleModelId.selectedOption, "") : null, : null,
hint: "Model", hint: LocaleKeys.brand.tr(),
errorValue: requestsVM.vehicleModelId.errorValue, errorValue:
); requestsVM.vehicleBrandId.errorValue,
}), );
8.height, }),
Builder(builder: (context) { 8.height,
List<DropValue> vehicleYearModelsDrop = []; Builder(builder: (context) {
for (var element in requestsVM.vehicleModelYears) { List<DropValue> vehicleModelsDrop = [];
vehicleYearModelsDrop.add(DropValue(element.id?.toInt() ?? 0, element.modelYear ?? "", "")); for (var element in requestsVM.vehicleModels) {
} if (requestsVM.vehicleBrandId.selectedId ==
element.vehicleBrandID)
vehicleModelsDrop.add(DropValue(
element.id?.toInt() ?? 0,
element.model ?? "",
""));
}
return DropdownField(
(DropValue value) =>
requestsVM.updateSelectionVehicleModelId(
SelectionModel(
selectedId: value.id,
selectedOption: value.value)),
list: vehicleModelsDrop,
dropdownValue:
requestsVM.vehicleModelId.selectedId != -1
? DropValue(
requestsVM
.vehicleModelId.selectedId,
requestsVM
.vehicleModelId.selectedOption,
"")
: null,
hint: LocaleKeys.model.tr(),
errorValue:
requestsVM.vehicleModelId.errorValue,
);
}),
8.height,
Builder(builder: (context) {
List<DropValue> vehicleYearModelsDrop = [];
for (var element
in requestsVM.vehicleModelYears) {
vehicleYearModelsDrop.add(DropValue(
element.id?.toInt() ?? 0,
element.modelYear ?? "",
""));
}
return DropdownField( return DropdownField(
(DropValue value) => requestsVM.updateSelectionVehicleModelYearId(SelectionModel(selectedId: value.id, selectedOption: value.value)), (DropValue value) => requestsVM
list: vehicleYearModelsDrop, .updateSelectionVehicleModelYearId(
dropdownValue: SelectionModel(
requestsVM.vehicleModelYearId.selectedId != -1 ? DropValue(requestsVM.vehicleModelYearId.selectedId, requestsVM.vehicleModelYearId.selectedOption, "") : null, selectedId: value.id,
hint: "Year", selectedOption: value.value)),
errorValue: requestsVM.vehicleModelYearId.errorValue, list: vehicleYearModelsDrop,
); dropdownValue:
}), requestsVM.vehicleModelYearId.selectedId !=
8.height, -1
Builder(builder: (context) { ? DropValue(
List<DropValue> vehicleCountriesDrop = []; requestsVM
for (var element in requestsVM.vehicleCountries) { .vehicleModelYearId.selectedId,
vehicleCountriesDrop.add(DropValue(element.id?.toInt() ?? 0, element.countryName ?? "", "")); requestsVM.vehicleModelYearId
} .selectedOption,
return DropdownField( "")
(DropValue value) => requestsVM.updateSelectionVehicleCountryId(SelectionModel(selectedOption: value.value, selectedId: value.id)), : null,
list: vehicleCountriesDrop, hint: LocaleKeys.year.tr(),
dropdownValue: requestsVM.vehicleCountryId.selectedId != -1 errorValue:
? DropValue(requestsVM.vehicleCountryId.selectedId, requestsVM.vehicleCountryId.selectedOption, "") requestsVM.vehicleModelYearId.errorValue,
: null, );
hint: "Country", }),
errorValue: requestsVM.vehicleCountryId.errorValue, 8.height,
); Builder(builder: (context) {
}), List<DropValue> vehicleCountriesDrop = [];
if (requestsVM.vehicleCountryId.selectedId != -1) ...[ for (var element in requestsVM.vehicleCountries) {
if (requestsVM.isCountryFetching) ...[ vehicleCountriesDrop.add(DropValue(
Row( element.id?.toInt() ?? 0,
mainAxisAlignment: MainAxisAlignment.center, element.countryName ?? "",
children: [const CircularProgressIndicator().paddingAll(10)], ""));
), }
] else return DropdownField(
...[ (DropValue value) =>
8.height, requestsVM.updateSelectionVehicleCountryId(
Builder(builder: (context) { SelectionModel(
List<DropValue> vehicleCitiesDrop = []; selectedOption: value.value,
for (var element in requestsVM.vehicleCities) { selectedId: value.id)),
vehicleCitiesDrop.add(DropValue(element.id?.toInt() ?? 0, element.cityName ?? "", "")); list: vehicleCountriesDrop,
} dropdownValue:
return DropdownField( requestsVM.vehicleCountryId.selectedId != -1
(DropValue value) => requestsVM.updateSelectionVehicleCityId(SelectionModel(selectedId: value.id, selectedOption: value.value)), ? DropValue(
list: vehicleCitiesDrop, requestsVM
dropdownValue: requestsVM.vehicleCityId.selectedId != -1 ? DropValue(requestsVM.vehicleCityId.selectedId, requestsVM.vehicleCityId.selectedOption, "") : null, .vehicleCountryId.selectedId,
hint: "City", requestsVM.vehicleCountryId
errorValue: requestsVM.vehicleCityId.errorValue, .selectedOption,
); "")
}), : null,
], hint: LocaleKeys.country.tr(),
], errorValue:
8.height, requestsVM.vehicleCountryId.errorValue,
TxtField( );
hint: "Price", }),
value: requestsVM.price, if (requestsVM.vehicleCountryId.selectedId !=
keyboardType: TextInputType.number, -1) ...[
onChanged: (e) => requestsVM.updatePrice(e), if (requestsVM.isCountryFetching) ...[
),
8.height,
TxtField(
hint: "Description",
maxLines: 5,
value: requestsVM.description,
onChanged: (e) => requestsVM.updateDescription(e),
),
8.height,
DottedRectContainer(
onTap: () => context.read<RequestsVM>().pickMultipleImages(),
text: "Attach Image",
icon: MyAssets.attachmentIcon.buildSvg(),
),
if (requestsVM.vehicleImageError != "") ...[
10.height,
Row( Row(
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
requestsVM.vehicleImageError.toText(fontSize: 14, color: Colors.red), const CircularProgressIndicator()
.paddingAll(10)
], ],
).paddingOnly(right: 10)
],
if (requestsVM.pickedVehicleImages.isNotEmpty) ...[
16.height,
PickedFilesContainer(
pickedFiles: requestsVM.pickedVehicleImages,
onCrossPressedPrimary: requestsVM.removeImageFromList,
onAddFilePressed: () {
context.read<RequestsVM>().pickMultipleImages();
},
), ),
] else ...[
8.height,
Builder(builder: (context) {
List<DropValue> vehicleCitiesDrop = [];
for (var element
in requestsVM.vehicleCities) {
vehicleCitiesDrop.add(DropValue(
element.id?.toInt() ?? 0,
element.cityName ?? "",
""));
}
return DropdownField(
(DropValue value) =>
requestsVM.updateSelectionVehicleCityId(
SelectionModel(
selectedId: value.id,
selectedOption: value.value)),
list: vehicleCitiesDrop,
dropdownValue: requestsVM
.vehicleCityId.selectedId !=
-1
? DropValue(
requestsVM.vehicleCityId.selectedId,
requestsVM
.vehicleCityId.selectedOption,
"")
: null,
hint: LocaleKeys.city.tr(),
errorValue:
requestsVM.vehicleCityId.errorValue,
);
}),
], ],
16.height, ],
8.height,
TxtField(
hint: LocaleKeys.price.tr(),
value: requestsVM.price,
keyboardType: TextInputType.number,
onChanged: (e) => requestsVM.updatePrice(e),
),
8.height,
TxtField(
hint: LocaleKeys.description.tr(),
maxLines: 5,
value: requestsVM.description,
onChanged: (e) => requestsVM.updateDescription(e),
),
8.height,
DottedRectContainer(
onTap: () => context
.read<RequestsVM>()
.pickMultipleImages(),
text: LocaleKeys.attachImage.tr(),
icon: MyAssets.attachmentIcon.buildSvg(),
),
if (requestsVM.vehicleImageError != "") ...[
10.height,
Row( Row(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.end,
children: [ children: [
Checkbox( requestsVM.vehicleImageError
value: requestsVM.isShippingDeliveryEnabled, .toText(fontSize: 14, color: Colors.red),
onChanged: null,
),
"Shipping/Delivery".toText(color: MyColors.darkPrimaryColor, isBold: true, fontSize: 18)
], ],
).onPress(() { ).paddingOnly(right: 10)
requestsVM.updateShippingDeliverEnabled(!requestsVM.isShippingDeliveryEnabled);
}),
], ],
), if (requestsVM.pickedVehicleImages.isNotEmpty) ...[
] 16.height,
PickedFilesContainer(
pickedFiles: requestsVM.pickedVehicleImages,
onCrossPressedPrimary:
requestsVM.removeImageFromList,
onAddFilePressed: () {
context
.read<RequestsVM>()
.pickMultipleImages();
},
),
],
16.height,
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Checkbox(
value: requestsVM.isShippingDeliveryEnabled,
onChanged: null,
),
LocaleKeys.shippingDelivery.tr().toText(
color: MyColors.darkPrimaryColor,
isBold: true,
fontSize: 18)
],
).onPress(() {
requestsVM.updateShippingDeliverEnabled(
!requestsVM.isShippingDeliveryEnabled);
}),
],
),
]
], ],
).toContainer(isShadowEnabled: true, marginAll: 16, paddingAll: 12), ).toContainer(
isShadowEnabled: true, marginAll: 16, paddingAll: 12),
), ),
), ),
ShowFillButton( ShowFillButton(
title: "Create Request", title: LocaleKeys.createRequest.tr(),
maxWidth: double.infinity, maxWidth: double.infinity,
margin: const EdgeInsets.all(16), margin: const EdgeInsets.all(16),
onPressed: () async { onPressed: () async {

@ -5,6 +5,7 @@ import 'package:mc_common_app/classes/app_state.dart';
import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/config/routes.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/models/requests_models/provider_offers_model.dart'; import 'package:mc_common_app/models/requests_models/provider_offers_model.dart';
import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/enums.dart';
@ -13,6 +14,7 @@ import 'package:mc_common_app/view_models/chat_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/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart';
class OfferListPage extends StatelessWidget { class OfferListPage extends StatelessWidget {
final OfferListPageArguments offerListPageArguments; final OfferListPageArguments offerListPageArguments;
@ -21,23 +23,29 @@ class OfferListPage extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final List<ServiceProvidersOffers> serviceProviderOffers = offerListPageArguments.serviceProviderOffers; final List<ServiceProvidersOffers> serviceProviderOffers =
offerListPageArguments.serviceProviderOffers;
return Scaffold( return Scaffold(
appBar: const CustomAppBar(title: "Offers"), appBar: CustomAppBar(title: LocaleKeys.offers.tr()),
body: serviceProviderOffers.isEmpty body: serviceProviderOffers.isEmpty
? Center(child: "No Offers to show.".toText(fontSize: 16, color: MyColors.lightTextColor)) ? Center(
child: LocaleKeys.noOffersShow
.tr()
.toText(fontSize: 16, color: MyColors.lightTextColor))
: ListView.separated( : ListView.separated(
itemCount: serviceProviderOffers.length, itemCount: serviceProviderOffers.length,
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
itemBuilder: (context, index) { itemBuilder: (context, index) {
ServiceProvidersOffers offersModel = serviceProviderOffers[index]; ServiceProvidersOffers offersModel =
serviceProviderOffers[index];
return Column( return Column(
children: [ children: [
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
(offersModel.name ?? "").toText(fontSize: 16, isBold: true), (offersModel.name ?? "")
.toText(fontSize: 16, isBold: true),
Center( Center(
child: "${offersModel.offerCount}".toText( child: "${offersModel.offerCount}".toText(
color: Colors.white, color: Colors.white,
@ -82,10 +90,12 @@ class OfferListPage extends StatelessWidget {
ChatViewArguments chatViewArguments = ChatViewArguments( ChatViewArguments chatViewArguments = ChatViewArguments(
chatTypeEnum: ChatTypeEnum.requestOffer, chatTypeEnum: ChatTypeEnum.requestOffer,
receiverId: "${offersModel.providerUserId}", receiverId: "${offersModel.providerUserId}",
senderId: AppState().getUser.data!.userInfo!.userId.toString(), senderId:
AppState().getUser.data!.userInfo!.userId.toString(),
requestId: offerListPageArguments.requestId, requestId: offerListPageArguments.requestId,
providerIndex: index, providerIndex: index,
requestIndex: -1, // This will be only send in case of provider requestIndex:
-1, // This will be only send in case of provider
); );
final chatVM = context.read<ChatVM>(); final chatVM = context.read<ChatVM>();
@ -99,7 +109,8 @@ class OfferListPage extends StatelessWidget {
providerOfferIndex: index, providerOfferIndex: index,
) )
.whenComplete( .whenComplete(
() => navigateWithName(context, AppRoutes.chatView, arguments: chatViewArguments), () => navigateWithName(context, AppRoutes.chatView,
arguments: chatViewArguments),
); );
}).toContainer(isShadowEnabled: true); }).toContainer(isShadowEnabled: true);
}, },

@ -2,6 +2,7 @@
import 'dart:developer'; import 'dart:developer';
import 'package:mc_common_app/generated/locale_keys.g.dart';
import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/view_models/chat_view_model.dart'; import 'package:mc_common_app/view_models/chat_view_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -14,13 +15,18 @@ import 'package:mc_common_app/utils/navigator.dart';
import 'package:mc_common_app/utils/utils.dart'; import 'package:mc_common_app/utils/utils.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:easy_localization/easy_localization.dart';
class RequestItem extends StatelessWidget { class RequestItem extends StatelessWidget {
final RequestModel request; final RequestModel request;
final AppType appType; final AppType appType;
final int requestIndex; final int requestIndex;
const RequestItem({super.key, required this.request, required this.appType, required this.requestIndex}); const RequestItem(
{super.key,
required this.request,
required this.appType,
required this.requestIndex});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -34,11 +40,16 @@ class RequestItem extends StatelessWidget {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Utils.statusContainerChip(text: request.requestStatusName, chipColor: Utils.getChipColorByRequestStatus(request.requestStatus)), Utils.statusContainerChip(
text: request.requestStatusName,
chipColor: Utils.getChipColorByRequestStatus(
request.requestStatus)),
6.height, 6.height,
"${request.brand} ${request.model}".toText(fontSize: 16, isBold: true), "${request.brand} ${request.model}"
showItem("Model:", "${request.year}"), .toText(fontSize: 16, isBold: true),
showItem("Customer Name:", request.customerName), showItem((LocaleKeys.model.tr()), "${request.year}"),
showItem(
(LocaleKeys.customerName.tr()), request.customerName),
], ],
), ),
), ),
@ -72,7 +83,7 @@ class RequestItem extends StatelessWidget {
) )
], ],
), ),
showItem("Description: ", request.description), showItem((LocaleKeys.description.tr()), request.description),
showItem("Price Range: ", ""), showItem("Price Range: ", ""),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -87,7 +98,8 @@ class RequestItem extends StatelessWidget {
isBold: true, isBold: true,
), ),
2.width, 2.width,
"SAR" LocaleKeys.sar
.tr()
.toText( .toText(
color: MyColors.lightTextColor, color: MyColors.lightTextColor,
fontSize: 10, fontSize: 10,
@ -110,13 +122,20 @@ class RequestItem extends StatelessWidget {
return; return;
} }
if (appType == AppType.provider) { if (appType == AppType.provider) {
RequestDetailPageArguments requestDetailPageArguments = RequestDetailPageArguments(requestIndex: requestIndex, requestModel: request); RequestDetailPageArguments requestDetailPageArguments =
navigateWithName(context, AppRoutes.requestsDetailPage, arguments: requestDetailPageArguments); RequestDetailPageArguments(
requestIndex: requestIndex, requestModel: request);
navigateWithName(context, AppRoutes.requestsDetailPage,
arguments: requestDetailPageArguments);
} else { } else {
ChatVM chatVM = context.read<ChatVM>(); ChatVM chatVM = context.read<ChatVM>();
await chatVM.getOffersFromProvidersByRequest(requestId: request.id, context: context); await chatVM.getOffersFromProvidersByRequest(
OfferListPageArguments offerListPageArguments = OfferListPageArguments(serviceProviderOffers: chatVM.serviceProviderOffersList, requestId: request.id); requestId: request.id, context: context);
navigateWithName(context, AppRoutes.offersListPage, arguments: offerListPageArguments); OfferListPageArguments offerListPageArguments = OfferListPageArguments(
serviceProviderOffers: chatVM.serviceProviderOffersList,
requestId: request.id);
navigateWithName(context, AppRoutes.offersListPage,
arguments: offerListPageArguments);
} }
}); });
} }

@ -34,7 +34,8 @@ class _ProviderLicensePageState extends State<ProviderLicensePage> {
// TODO: implement initState // TODO: implement initState
super.initState(); super.initState();
branchVM = Provider.of<ServiceVM>(context, listen: false); branchVM = Provider.of<ServiceVM>(context, listen: false);
branchVM.getServiceProviderDocument(AppState().getUser.data!.userInfo!.providerId ?? 0); branchVM.getServiceProviderDocument(
AppState().getUser.data!.userInfo!.providerId ?? 0);
} }
@override @override
@ -73,7 +74,9 @@ class _ProviderLicensePageState extends State<ProviderLicensePage> {
if (validation(model)) { if (validation(model)) {
updateDocument(model); updateDocument(model);
} else { } else {
Utils.showToast("All document's are mandatory for Dealership Provider"); Utils.showToast(LocaleKeys
.allDocumentMandatoryDealershipProvider
.tr());
} }
} else { } else {
updateDocument(model); updateDocument(model);
@ -102,7 +105,7 @@ class _ProviderLicensePageState extends State<ProviderLicensePage> {
MResponse res = await model.updateDocument(model.document!.data); MResponse res = await model.updateDocument(model.document!.data);
Utils.hideLoading(context); Utils.hideLoading(context);
if (res.messageStatus == 1) { if (res.messageStatus == 1) {
Utils.showToast("Documents uploaded successfully"); Utils.showToast(LocaleKeys.documentsUploadedSuccessfully.tr());
} else { } else {
Utils.showToast(res.message ?? ""); Utils.showToast(res.message ?? "");
} }
@ -111,7 +114,7 @@ class _ProviderLicensePageState extends State<ProviderLicensePage> {
Widget showWidget(ServiceVM model) { Widget showWidget(ServiceVM model) {
if (model.state == ViewState.idle) { if (model.state == ViewState.idle) {
return model.document!.data!.isEmpty return model.document!.data!.isEmpty
? Text("LocaleKeys.somethingWrong.tr()") ? Text(LocaleKeys.somethingWrong.tr())
: ListView.separated( : ListView.separated(
itemBuilder: (context, index) { itemBuilder: (context, index) {
return Column( return Column(
@ -124,19 +127,27 @@ class _ProviderLicensePageState extends State<ProviderLicensePage> {
), ),
), ),
Padding( Padding(
padding: const EdgeInsets.only(left: 20, right: 20, top: 4, bottom: 8), padding: const EdgeInsets.only(
child: LocaleKeys.enter_licence_detail.tr().toText(fontSize: 14, color: MyColors.lightTextColor, textAlign: TextAlign.center), left: 20, right: 20, top: 4, bottom: 8),
child: LocaleKeys.enter_licence_detail.tr().toText(
fontSize: 14,
color: MyColors.lightTextColor,
textAlign: TextAlign.center),
), ),
TxtField( TxtField(
hint: LocaleKeys.description.tr(), hint: LocaleKeys.description.tr(),
maxLines: 3, maxLines: 3,
isBackgroundEnabled: true, isBackgroundEnabled: true,
), ),
if ((model.document?.data![index].documentUrl ?? "").toString().isNotEmpty) if ((model.document?.data![index].documentUrl ?? "")
.toString()
.isNotEmpty)
Column( Column(
children: [ children: [
8.height, 8.height,
(model.document?.data![index].documentUrl ?? "").toString().toText( (model.document?.data![index].documentUrl ?? "")
.toString()
.toText(
fontSize: 14, fontSize: 14,
color: MyColors.lightTextColor, color: MyColors.lightTextColor,
), ),
@ -152,8 +163,10 @@ class _ProviderLicensePageState extends State<ProviderLicensePage> {
height: 45, height: 45,
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.transparent, color: Colors.transparent,
border: Border.all(color: MyColors.greyACColor, width: 2), border:
borderRadius: const BorderRadius.all(Radius.circular(0)), Border.all(color: MyColors.greyACColor, width: 2),
borderRadius:
const BorderRadius.all(Radius.circular(0)),
), ),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,

@ -2,9 +2,11 @@ import 'package:flutter/material.dart';
import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/config/routes.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/utils/navigator.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/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:easy_localization/easy_localization.dart';
class SettingOptionsHelp extends StatelessWidget { class SettingOptionsHelp extends StatelessWidget {
const SettingOptionsHelp({super.key}); const SettingOptionsHelp({super.key});
@ -13,7 +15,7 @@ class SettingOptionsHelp extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: CustomAppBar( appBar: CustomAppBar(
title: "Help", title: LocaleKeys.help.tr(),
isRemoveBackButton: false, isRemoveBackButton: false,
isDrawerEnabled: false, isDrawerEnabled: false,
onBackButtonTapped: () => Navigator.pop(context), onBackButtonTapped: () => Navigator.pop(context),
@ -27,23 +29,30 @@ class SettingOptionsHelp extends StatelessWidget {
children: [ children: [
CustomSettingOptionsTile( CustomSettingOptionsTile(
leadingWidget: const Icon(Icons.info_rounded, size: 20), leadingWidget: const Icon(Icons.info_rounded, size: 20),
titleText: "FAQs", titleText: LocaleKeys.faqs.tr(),
needBorderBelow: true, needBorderBelow: true,
onTap: () {}, onTap: () {},
), ),
CustomSettingOptionsTile( CustomSettingOptionsTile(
leadingWidget: const Icon(Icons.mail, size: 20), leadingWidget: const Icon(Icons.mail, size: 20),
titleText: "Contact Us", titleText: LocaleKeys.contactUs.tr(),
needBorderBelow: true, needBorderBelow: true,
onTap: () => navigateWithName(context, AppRoutes.settingOptionsFaqs), onTap: () => navigateWithName(
context, AppRoutes.settingOptionsFaqs),
), ),
CustomSettingOptionsTile( CustomSettingOptionsTile(
leadingWidget: const Icon(Icons.lock, size: 20), leadingWidget: const Icon(Icons.lock, size: 20),
titleText: "Term & Privacy", titleText: LocaleKeys.termPrivacy.tr(),
onTap: () => navigateWithName(context, AppRoutes.profileView), onTap: () =>
navigateWithName(context, AppRoutes.profileView),
), ),
], ],
).toContainer(width: double.infinity, isShadowEnabled: true, paddingAll: 10, margin: const EdgeInsets.fromLTRB(24, 24, 24, 0), borderRadius: 0), ).toContainer(
width: double.infinity,
isShadowEnabled: true,
paddingAll: 10,
margin: const EdgeInsets.fromLTRB(24, 24, 24, 0),
borderRadius: 0),
], ],
), ),
), ),
@ -60,7 +69,13 @@ class CustomSettingOptionsTile extends StatelessWidget {
final bool isForLanguage; final bool isForLanguage;
final Function() onTap; final Function() onTap;
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});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -76,7 +91,9 @@ class CustomSettingOptionsTile extends StatelessWidget {
titleText.toText(fontSize: 16), titleText.toText(fontSize: 16),
], ],
), ),
isForLanguage ? const Icon(Icons.language, size: 18) : const Icon(Icons.arrow_forward, size: 18) isForLanguage
? const Icon(Icons.language, size: 18)
: const Icon(Icons.arrow_forward, size: 18)
], ],
).onPress(onTap), ).onPress(onTap),
5.height, 5.height,

@ -1,8 +1,10 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.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/views/setting_options/widgets/custom_setting_options_tile.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:mc_common_app/widgets/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:easy_localization/easy_localization.dart';
class SettingOptionsFAQs extends StatelessWidget { class SettingOptionsFAQs extends StatelessWidget {
const SettingOptionsFAQs({super.key}); const SettingOptionsFAQs({super.key});
@ -11,7 +13,7 @@ class SettingOptionsFAQs extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: CustomAppBar( appBar: CustomAppBar(
title: "More", title: LocaleKeys.more.tr(),
isRemoveBackButton: false, isRemoveBackButton: false,
isDrawerEnabled: false, isDrawerEnabled: false,
onBackButtonTapped: () => Navigator.pop(context), onBackButtonTapped: () => Navigator.pop(context),
@ -23,11 +25,27 @@ class SettingOptionsFAQs extends StatelessWidget {
children: [ children: [
Column( Column(
children: [ children: [
CustomSettingOptionsTile(leadingWidget: const Icon(Icons.info, size: 20), titleText: "FAQs", needBorderBelow: true, onTap: () {}), CustomSettingOptionsTile(
CustomSettingOptionsTile(leadingWidget: const Icon(Icons.mail, size: 20), titleText: "Contact Us", needBorderBelow: true, onTap: () {}), leadingWidget: const Icon(Icons.info, size: 20),
CustomSettingOptionsTile(leadingWidget: const Icon(Icons.settings, size: 20), titleText: "Terms & Privacy", onTap: () {}), titleText: LocaleKeys.faqs.tr(),
needBorderBelow: true,
onTap: () {}),
CustomSettingOptionsTile(
leadingWidget: const Icon(Icons.mail, size: 20),
titleText: LocaleKeys.contactUs.tr(),
needBorderBelow: true,
onTap: () {}),
CustomSettingOptionsTile(
leadingWidget: const Icon(Icons.settings, size: 20),
titleText: LocaleKeys.termPrivacy.tr(),
onTap: () {}),
], ],
).toContainer(width: double.infinity, isShadowEnabled: true, paddingAll: 10, margin: const EdgeInsets.fromLTRB(24, 24, 24, 0), borderRadius: 0), ).toContainer(
width: double.infinity,
isShadowEnabled: true,
paddingAll: 10,
margin: const EdgeInsets.fromLTRB(24, 24, 24, 0),
borderRadius: 0),
], ],
), ),
), ),

@ -2,9 +2,11 @@ import 'package:flutter/material.dart';
import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/config/routes.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/utils/navigator.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/common_widgets/app_bar.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:easy_localization/easy_localization.dart';
class SettingOptionsInviteFriends extends StatelessWidget { class SettingOptionsInviteFriends extends StatelessWidget {
const SettingOptionsInviteFriends({super.key}); const SettingOptionsInviteFriends({super.key});
@ -13,7 +15,7 @@ class SettingOptionsInviteFriends extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: CustomAppBar( appBar: CustomAppBar(
title: "More", title: LocaleKeys.more.tr(),
isRemoveBackButton: false, isRemoveBackButton: false,
isDrawerEnabled: false, isDrawerEnabled: false,
onBackButtonTapped: () => Navigator.pop(context), onBackButtonTapped: () => Navigator.pop(context),
@ -27,23 +29,30 @@ class SettingOptionsInviteFriends extends StatelessWidget {
children: [ children: [
CustomSettingOptionsTile( CustomSettingOptionsTile(
leadingWidget: const Icon(Icons.person, size: 20), leadingWidget: const Icon(Icons.person, size: 20),
titleText: "Invite Friends", titleText: LocaleKeys.inviteFriends.tr(),
needBorderBelow: true, needBorderBelow: true,
onTap: () {}, onTap: () {},
), ),
CustomSettingOptionsTile( CustomSettingOptionsTile(
leadingWidget: const Icon(Icons.help, size: 20), leadingWidget: const Icon(Icons.help, size: 20),
titleText: "Help", titleText: LocaleKeys.help.tr(),
needBorderBelow: true, needBorderBelow: true,
onTap: () => navigateWithName(context, AppRoutes.settingOptionsFaqs), onTap: () => navigateWithName(
context, AppRoutes.settingOptionsFaqs),
), ),
CustomSettingOptionsTile( CustomSettingOptionsTile(
leadingWidget: const Icon(Icons.person, size: 20), leadingWidget: const Icon(Icons.person, size: 20),
titleText: "Account", titleText: LocaleKeys.account.tr(),
onTap: () => navigateWithName(context, AppRoutes.profileView), onTap: () =>
navigateWithName(context, AppRoutes.profileView),
), ),
], ],
).toContainer(width: double.infinity, isShadowEnabled: true, paddingAll: 10, margin: const EdgeInsets.fromLTRB(24, 24, 24, 0), borderRadius: 0), ).toContainer(
width: double.infinity,
isShadowEnabled: true,
paddingAll: 10,
margin: const EdgeInsets.fromLTRB(24, 24, 24, 0),
borderRadius: 0),
], ],
), ),
), ),
@ -60,7 +69,13 @@ class CustomSettingOptionsTile extends StatelessWidget {
final bool isForLanguage; final bool isForLanguage;
final Function() onTap; final Function() onTap;
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});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -76,7 +91,9 @@ class CustomSettingOptionsTile extends StatelessWidget {
titleText.toText(fontSize: 16), titleText.toText(fontSize: 16),
], ],
), ),
isForLanguage ? const Icon(Icons.language, size: 18) : const Icon(Icons.arrow_forward, size: 18) isForLanguage
? const Icon(Icons.language, size: 18)
: const Icon(Icons.arrow_forward, size: 18)
], ],
).onPress(onTap), ).onPress(onTap),
5.height, 5.height,

@ -5,6 +5,7 @@ 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/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/int_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/theme/colors.dart';
import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/enums.dart';
import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/utils/navigator.dart';
@ -22,7 +23,7 @@ class SettingOptionsLanguage extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: CustomAppBar( appBar: CustomAppBar(
title: "More", title: LocaleKeys.more.tr(),
isRemoveBackButton: false, isRemoveBackButton: false,
isDrawerEnabled: false, isDrawerEnabled: false,
onBackButtonTapped: () => Navigator.pop(context), onBackButtonTapped: () => Navigator.pop(context),
@ -39,8 +40,9 @@ class SettingOptionsLanguage extends StatelessWidget {
Column( Column(
children: [ children: [
CustomSettingOptionsTile( CustomSettingOptionsTile(
leadingWidget: const Icon(Icons.quickreply_outlined, size: 20), leadingWidget:
titleText: "Requests", const Icon(Icons.quickreply_outlined, size: 20),
titleText: LocaleKeys.requests.tr(),
needBorderBelow: true, needBorderBelow: true,
onTap: () { onTap: () {
context.read<DashboardVmCustomer>().onNavbarTapped(4); context.read<DashboardVmCustomer>().onNavbarTapped(4);
@ -48,20 +50,22 @@ class SettingOptionsLanguage extends StatelessWidget {
}), }),
CustomSettingOptionsTile( CustomSettingOptionsTile(
leadingWidget: const Icon(Icons.settings, size: 20), leadingWidget: const Icon(Icons.settings, size: 20),
titleText: "Settings", titleText: LocaleKeys.settings.tr(),
needBorderBelow: true, needBorderBelow: true,
onTap: () {}, onTap: () {},
//navigateWithName(context, AppRoutes.settingOptionsInviteFriends), //navigateWithName(context, AppRoutes.settingOptionsInviteFriends),
), ),
CustomSettingOptionsTile( CustomSettingOptionsTile(
leadingWidget: const Icon(Icons.question_mark_outlined, size: 20), leadingWidget:
titleText: "Help", const Icon(Icons.question_mark_outlined, size: 20),
titleText: LocaleKeys.help.tr(),
needBorderBelow: true, needBorderBelow: true,
onTap: () => navigateWithName(context, AppRoutes.settingOptionsHelp), onTap: () =>
navigateWithName(context, AppRoutes.settingOptionsHelp),
), ),
CustomSettingOptionsTile( CustomSettingOptionsTile(
leadingWidget: const Icon(Icons.person, size: 20), leadingWidget: const Icon(Icons.person, size: 20),
titleText: "Account", titleText: LocaleKeys.account.tr(),
needBorderBelow: false, needBorderBelow: false,
onTap: () { onTap: () {
navigateWithName(context, AppRoutes.profileView); navigateWithName(context, AppRoutes.profileView);
@ -69,20 +73,29 @@ class SettingOptionsLanguage extends StatelessWidget {
// Navigator.pop(context); // Navigator.pop(context);
}), }),
], ],
).toWhiteContainer(width: double.infinity, pading: const EdgeInsets.all(12), borderRadius: 0), ).toWhiteContainer(
width: double.infinity,
pading: const EdgeInsets.all(12),
borderRadius: 0),
10.height, 10.height,
CustomSettingOptionsTile( CustomSettingOptionsTile(
leadingWidget: const Icon(Icons.translate, size: 20), leadingWidget: const Icon(Icons.translate, size: 20),
titleText: "Language", titleText: LocaleKeys.language.tr(),
isForLanguage: true, isForLanguage: true,
onTap: () { onTap: () {
if (EasyLocalization.of(context)?.currentLocale?.countryCode == "SA") { 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'));
} }
}, },
).toWhiteContainer(width: double.infinity, pading: const EdgeInsets.all(12), borderRadius: 0), ).toWhiteContainer(
width: double.infinity,
pading: const EdgeInsets.all(12),
borderRadius: 0),
10.height, 10.height,
(AppState().currentAppType == AppType.provider) (AppState().currentAppType == AppType.provider)
? Column( ? Column(
@ -96,12 +109,13 @@ class SettingOptionsLanguage extends StatelessWidget {
color: MyColors.primaryColor, color: MyColors.primaryColor,
), ),
), ),
titleText: "My Subscriptions", titleText: LocaleKeys.mySubscriptions.tr(),
subTitle: "Silver", subTitle: "Silver",
isForLanguage: false, isForLanguage: false,
needBorderBelow: true, needBorderBelow: true,
onTap: () { onTap: () {
navigateWithName(context, AppRoutes.mySubscriptionsPage); navigateWithName(
context, AppRoutes.mySubscriptionsPage);
}, },
), ),
CustomSettingOptionsTile( CustomSettingOptionsTile(
@ -113,12 +127,13 @@ class SettingOptionsLanguage extends StatelessWidget {
// color: MyColors.primaryColor, // color: MyColors.primaryColor,
), ),
), ),
titleText: "Subscriptions", titleText: LocaleKeys.subscriptions.tr(),
subTitle: null, subTitle: null,
isForLanguage: false, isForLanguage: false,
needBorderBelow: true, needBorderBelow: true,
onTap: () { onTap: () {
navigateWithName(context, AppRoutes.subscriptionsPage); navigateWithName(
context, AppRoutes.subscriptionsPage);
}, },
), ),
CustomSettingOptionsTile( CustomSettingOptionsTile(
@ -130,18 +145,24 @@ class SettingOptionsLanguage extends StatelessWidget {
// color: MyColors.primaryColor, // color: MyColors.primaryColor,
), ),
), ),
titleText: "Define Licenses", titleText: LocaleKeys.defineLicenses.tr(),
subTitle: null, subTitle: null,
isForLanguage: false, isForLanguage: false,
needBorderBelow: false, needBorderBelow: false,
onTap: () { onTap: () {
navigateWithName(context, AppRoutes.providerLicensePage); navigateWithName(
context, AppRoutes.providerLicensePage);
}, },
) )
], ],
).toWhiteContainer(width: double.infinity, pading: const EdgeInsets.all(12), borderRadius: 0) ).toWhiteContainer(
width: double.infinity,
pading: const EdgeInsets.all(12),
borderRadius: 0)
: SizedBox(),
(AppState().currentAppType == AppType.provider)
? 10.height
: SizedBox(), : SizedBox(),
(AppState().currentAppType == AppType.provider) ? 10.height : SizedBox(),
], ],
)), )),
// : Expanded( // : Expanded(
@ -167,7 +188,9 @@ class SettingOptionsLanguage extends StatelessWidget {
// ], // ],
// ), // ),
// ), // ),
(AppState().currentAppType == AppType.provider) ? const Text("Provider") : const Text("Customer"), (AppState().currentAppType == AppType.provider)
? Text(LocaleKeys.provider.tr())
: Text(LocaleKeys.customer.tr()),
Row( Row(
children: [ children: [
Expanded( Expanded(
@ -177,7 +200,7 @@ class SettingOptionsLanguage extends StatelessWidget {
isFilled: false, isFilled: false,
fontSize: 16, fontSize: 16,
maxHeight: 55, maxHeight: 55,
title: "Log Out", title: LocaleKeys.logOut.tr(),
onPressed: () {}, onPressed: () {},
), ),
), ),

@ -1,18 +1,22 @@
import 'dart:async'; import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:local_auth/local_auth.dart'; import 'package:local_auth/local_auth.dart';
import 'package:mc_common_app/classes/app_state.dart'; 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/dependencies.dart'; import 'package:mc_common_app/config/dependencies.dart';
import 'package:mc_common_app/config/routes.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';
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_image_button.dart'; import 'package:mc_common_app/widgets/button/show_image_button.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class LoginMethodSelectionPage extends StatefulWidget { class LoginMethodSelectionPage extends StatefulWidget {
@ -54,12 +58,14 @@ class _LoginMethodSelectionPageState extends State<LoginMethodSelectionPage> {
Expanded( Expanded(
child: ShowImageButton( child: ShowImageButton(
onClick: () { onClick: () {
userVM.verifiyAuth(context: context, userToken: widget.userToken, apptype: appState.currentAppType, loginType: "3" ); userVM.verifiyAuth(context: context, userToken: widget.userToken, apptype: appState.currentAppType, loginType: "3");
//userVM.performBasicOtpLoginSelectionPage(context, userToken: userToken,appType: appState.currentAppType); //userVM.performBasicOtpLoginSelectionPage(context, userToken: userToken,appType: appState.currentAppType);
}, },
title: LocaleKeys.fingerPrint.tr(), title: LocaleKeys.fingerPrint.tr(),
icon: MyAssets.icFingerprintSvg, icon: MyAssets.icFingerprintSvg,
isDisabled: userVM.isBioAvailable(Platform.isAndroid ? BiometricType.weak : BiometricType.fingerprint, ), isDisabled: userVM.isBioAvailable(
Platform.isAndroid ? BiometricType.weak : BiometricType.fingerprint,
),
), ),
), ),
20.width, 20.width,
@ -67,7 +73,7 @@ class _LoginMethodSelectionPageState extends State<LoginMethodSelectionPage> {
child: ShowImageButton( child: ShowImageButton(
onClick: () { onClick: () {
// userVM.performBasicOtpLoginSelectionPage(context, userToken: widget.userToken, appType: appState.currentAppType); // userVM.performBasicOtpLoginSelectionPage(context, userToken: widget.userToken, appType: appState.currentAppType);
userVM.verifiyAuth(context: context, userToken: widget.userToken, apptype: appState.currentAppType, loginType: "4" ); userVM.verifiyAuth(context: context, userToken: widget.userToken, apptype: appState.currentAppType, loginType: "4");
}, },
title: LocaleKeys.faceRecognition.tr(), title: LocaleKeys.faceRecognition.tr(),
icon: MyAssets.icFace, icon: MyAssets.icFace,
@ -82,7 +88,7 @@ class _LoginMethodSelectionPageState extends State<LoginMethodSelectionPage> {
Expanded( Expanded(
child: ShowImageButton( child: ShowImageButton(
onClick: () { onClick: () {
userVM.performBasicOtpLoginSelectionPage(context, userToken: widget.userToken, appType: appState.currentAppType,loginType: "1"); userVM.performBasicOtpLoginSelectionPage(context, userToken: widget.userToken, appType: appState.currentAppType, loginType: "1");
}, },
title: LocaleKeys.SMS.tr(), title: LocaleKeys.SMS.tr(),
icon: MyAssets.icSmsSvg, icon: MyAssets.icSmsSvg,
@ -101,6 +107,16 @@ class _LoginMethodSelectionPageState extends State<LoginMethodSelectionPage> {
), ),
], ],
), ),
150.height,
("Login To Another Account")
.toText(
fontSize: 20,
letterSpacing: -1.44,
)
.onPress(() {
userVM.otherLogin(context);
}),
30.height,
], ],
), ),
), ),

Loading…
Cancel
Save