diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index ff0440e..5aeb8dc 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -186,7 +186,7 @@ "updateBranch": "تحديث فرع", "branches": "الفروع", "requests": "الطلبات", - "noBranchFound" : "لم يتم العثور على فرع", + "noBranchFound": "لم يتم العثور على فرع", "onlyProviderApp": "نأسف هذا التطبيق فقط لمقدمي الخدمات", "pickAddress": "اختر العنوان", "pickLocation": "اختر الموقع", @@ -202,19 +202,19 @@ "completeProfile2": "اكمل الملف الشخصي 2/3", "completeProfile3": "اكمل الملف الشخصي 3/3", "provider": "مزود", - "noRequeststoShow" : "لا توجد طلبات للعرض", + "noRequeststoShow": "لا توجد طلبات للعرض", "myBranches": "فروعي", - "mergeAppointments" : "دمج المواعيد", - "addService" : "أضف الخدمة", - "selectServicestoAdd" : "حدد الخدمات التي تريد إضافتها", + "mergeAppointments": "دمج المواعيد", + "addService": "أضف الخدمة", + "selectServicestoAdd": "حدد الخدمات التي تريد إضافتها", "noServiceFound": "لم يتم العثور على الخدمة", - "selectItems" : "اختيار العناصر", - "noItemSelectedYet" : "لم يتم تحديد أي عنصر بعد", - "totalAdditionalAmount" : "إجمالي المبلغ الإضافي", - "sar" : "ريال سعودي", - "cancel" : "يلغي", - "add" : "يضيف", - "itemsAddedSuccessfully" : "تمت إضافة العناصر بنجاح", + "selectItems": "اختيار العناصر", + "noItemSelectedYet": "لم يتم تحديد أي عنصر بعد", + "totalAdditionalAmount": "إجمالي المبلغ الإضافي", + "sar": "ريال سعودي", + "cancel": "يلغي", + "add": "يضيف", + "itemsAddedSuccessfully": "تمت إضافة العناصر بنجاح", "pleaseSelectItems": "يرجى اختيار العناصر", "totalAmount": "المبلغ الإجمالي", "searchItems": "البحث عن العناصر", @@ -568,16 +568,17 @@ "customer": "العميل", "amountVAR": "كمية", "accept": "قبول", - "amountVAR": "كمية", "nowVar": "الآن", "whendoyouWanttoUpgrade": "متى تريد الترقية", "yourSubscriptionUpgradeAffectingFrom": "سيتم ترقية اشتراكك الآن. ساري المفعول من", "upgradeAfterCurrentExpiry": "الترقية بعد انتهاء الاشتراك الحالي", "yourSubscriptionUpgradeCurrentSubscriptionAffectingFrom": "سيتم ترقية اشتراكك بعد انتهاء اشتراكك الحالي. ساري المفعول من", "upgradeVar": "ترقية", - "whendoyouWanttoRenew" : "متى تريد التجديد", - "renewVar" : "تجديد", + "whendoyouWanttoRenew": "متى تريد التجديد", + "renewVar": "تجديد", "requestAlreadyInProgress": "هذا الطلب قيد التقدم بالفعل.", "acceptOfferConfirmation": "هل تريد قبول هذا العرض؟", - "acceptOfferConfirmationMessage": "سيتم قبول هذا العرض وستدفع المبلغ المطلوب للمشتري في وقت معين وإلا سيتم إلغاء هذا العرض." + "acceptOfferConfirmationMessage": "سيتم قبول هذا العرض وستدفع المبلغ المطلوب للمشتري في وقت معين وإلا سيتم إلغاء هذا العرض.", + "noUpcomingAppointments": "لا يوجد موعد قادم متاح", + "addNewAppointment": "إضافة موعد جديد" } \ No newline at end of file diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index b8245fe..2b85fb4 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -423,93 +423,93 @@ "reserveAd": "Reserve Ad", "reservationAmount": "Reservation Amount", "belowAmountPayLater": "Below Amount that you will pay later", - "carPrice":"Car Price", - "vatExcluded":"VAT Excluded", - "carInsuranceService":"Car insurance Service", - "toBeDecided":"To be Decided", - "registrationCarPlates":"Registration & Car Plates", - "homeDeliveryService":"Home Delivery Service", - "specialServicechargesInsuranceDeliveryLocation":"Special service charges will be added based on desired insurance and delivery Location", - "estimated":"Estimated", - "servicesReservingAd":"Some services are mandatory while reserving Ad", - "completeReservation":"Complete Reservation", - "contact":"Contact", - "setDateandTime":"Set Date and Time", - "selectOffice":"Select Office", - "availableSlots":"Available Slots", - "bookAndPay":"Book and Pay", - "reservationAmounts":"Reservation Amounts", - "tax":"Tax", + "carPrice": "Car Price", + "vatExcluded": "VAT Excluded", + "carInsuranceService": "Car insurance Service", + "toBeDecided": "To be Decided", + "registrationCarPlates": "Registration & Car Plates", + "homeDeliveryService": "Home Delivery Service", + "specialServicechargesInsuranceDeliveryLocation": "Special service charges will be added based on desired insurance and delivery Location", + "estimated": "Estimated", + "servicesReservingAd": "Some services are mandatory while reserving Ad", + "completeReservation": "Complete Reservation", + "contact": "Contact", + "setDateandTime": "Set Date and Time", + "selectOffice": "Select Office", + "availableSlots": "Available Slots", + "bookAndPay": "Book and Pay", + "reservationAmounts": "Reservation Amounts", + "tax": "Tax", "adsFilter": "Ads Filter", - "searchByCity":"Search By City", - "selectCity":"Select City", - "searchByBrandName":"Search By Brand Name", - "selectVehicleBrand":"Select Vehicle Brand", - "searchByVehicleYear":"Search By Vehicle Year", - "selectYear":"Select Year", - "searchByAdOwner":"Search By Ad Owner", - "selectOwner":"Select Owner", - "search":"Search", - "clearFilters":"Clear Filters", - "book":"Book", - "markAsSold":"Mark As Sold", - "deactivateAd":"Deactivate Ad", - "doWantDeactivateAd":"Do you want to the Deactivate this Ad?", - "stoptheBuyers":"We will stop showing this ad to the buyers", - "cancelReservation":"Cancel Reservation", - "reasonForCancellation":"Reason for Cancellation", - "doWantCancelReservation":"Do you want to cancel the reservation", - "yourAdVisibletoBuy.":"Your ad reservation will be cancelled and this ad will be again visible to everyone to buy", - "completeDeal":"Complete Deal", - "uploadBankReceipt":"Upload Bank Receipt", - "notesForAdmin":"Notes For Admin", - "extendAd":"Extend Ad", - "updateAdDetails":"Do you want to update the Ad Details", - "durationExtendingAd":"You can change the ad duration and details before extending the ad", - "waitingAdminsResponse":"Waiting for Admins Response", - "cancelledByOwner":"Cancelled by Owner", - "cancelledByAdmin":"Cancelled by Admin", - "reservationTimeOver":"Reservation Time Over", - "paymentVerified":"Payment Verified", - "rejectedFormAdmin":"Rejected form Admin", - "waitingAdminPost":"Waiting for admin to post", - "waitingAdminsApproval":"Waiting for Admins Approval", - "sold":"Sold", - "noAdsShow":"No Ads to show", - "damagePartList":"Damage Part List", - "searchPart":"Search Part", - "addSpecialService":"Add Special Service", - "vehicleVar":"Vehicle", - "detailsVar":"Details", - "damageVar":"Damage", + "searchByCity": "Search By City", + "selectCity": "Select City", + "searchByBrandName": "Search By Brand Name", + "selectVehicleBrand": "Select Vehicle Brand", + "searchByVehicleYear": "Search By Vehicle Year", + "selectYear": "Select Year", + "searchByAdOwner": "Search By Ad Owner", + "selectOwner": "Select Owner", + "search": "Search", + "clearFilters": "Clear Filters", + "book": "Book", + "markAsSold": "Mark As Sold", + "deactivateAd": "Deactivate Ad", + "doWantDeactivateAd": "Do you want to the Deactivate this Ad?", + "stoptheBuyers": "We will stop showing this ad to the buyers", + "cancelReservation": "Cancel Reservation", + "reasonForCancellation": "Reason for Cancellation", + "doWantCancelReservation": "Do you want to cancel the reservation", + "yourAdVisibletoBuy.": "Your ad reservation will be cancelled and this ad will be again visible to everyone to buy", + "completeDeal": "Complete Deal", + "uploadBankReceipt": "Upload Bank Receipt", + "notesForAdmin": "Notes For Admin", + "extendAd": "Extend Ad", + "updateAdDetails": "Do you want to update the Ad Details", + "durationExtendingAd": "You can change the ad duration and details before extending the ad", + "waitingAdminsResponse": "Waiting for Admins Response", + "cancelledByOwner": "Cancelled by Owner", + "cancelledByAdmin": "Cancelled by Admin", + "reservationTimeOver": "Reservation Time Over", + "paymentVerified": "Payment Verified", + "rejectedFormAdmin": "Rejected form Admin", + "waitingAdminPost": "Waiting for admin to post", + "waitingAdminsApproval": "Waiting for Admins Approval", + "sold": "Sold", + "noAdsShow": "No Ads to show", + "damagePartList": "Damage Part List", + "searchPart": "Search Part", + "addSpecialService": "Add Special Service", + "vehicleVar": "Vehicle", + "detailsVar": "Details", + "damageVar": "Damage", "partsVar": "Parts", - "additional":"Additional", - "review":"Review", + "additional": "Additional", + "review": "Review", "adVar": "Ad", - "updateAd":"Update Ad", - "createAd":"Create Ad", - "next":"Next", - "submitAd":"Submit Ad", - "selectAdType":"Select Ad Type", - "validUntilSubscriptionExpiration":"Valid Until Subscription Expiration", - "adsRemainingVar ":"Ads Remaining", - "youLeftAdsGivenSubscription":"You have left with 05 out of 50 ads given in the subscription.", - "updateSubscription":"Update Subscription", - "workInProgress":"Work In Progress", - "visitCompleted":"Visit Completed", - "youWantCancelAppointment":"Do you want to cancel this appointment?", - "appointmentCancelledCannotUndoAction":"Your appointment will be cancelled and you cannot undo this action.", - "appointment":"Appointment", - "rescheduleAppointment":"Reschedule Appointment", - "payforAppointment":"Pay for Appointment", - "appointmentsFilter":"Appointments Filter", - "searchByProvider":"Search By Provider", - "selectProvider":"Select Provider", - "searchByBranch":"Search By Branch", - "searchByCategory":"Search By Category", - "selectCategory":"Select Category", - "searchByService":"Search By Service", - "selectServices":"Select Services", + "updateAd": "Update Ad", + "createAd": "Create Ad", + "next": "Next", + "submitAd": "Submit Ad", + "selectAdType": "Select Ad Type", + "validUntilSubscriptionExpiration": "Valid Until Subscription Expiration", + "adsRemainingVar ": "Ads Remaining", + "youLeftAdsGivenSubscription": "You have left with 05 out of 50 ads given in the subscription.", + "updateSubscription": "Update Subscription", + "workInProgress": "Work In Progress", + "visitCompleted": "Visit Completed", + "youWantCancelAppointment": "Do you want to cancel this appointment?", + "appointmentCancelledCannotUndoAction": "Your appointment will be cancelled and you cannot undo this action.", + "appointment": "Appointment", + "rescheduleAppointment": "Reschedule Appointment", + "payforAppointment": "Pay for Appointment", + "appointmentsFilter": "Appointments Filter", + "searchByProvider": "Search By Provider", + "selectProvider": "Select Provider", + "searchByBranch": "Search By Branch", + "searchByCategory": "Search By Category", + "selectCategory": "Select Category", + "searchByService": "Search By Service", + "selectServices": "Select Services", "modifyPackage": "Modify Package", "schedule": "Schedule", "serviceLocation": "Service Location:", @@ -527,13 +527,13 @@ "dateAndTime": "Date and Time", "timeLocation": "Time & Location", "serviceCharges": "Service Charges", - "locationCharges" : "Location Charges", + "locationCharges": "Location Charges", "payableNow": "Payable Now", "remainingAmount": "Remaining Amount", "branchesFilter": "Branches Filter", -"searchByDistance": "Search By Distance", + "searchByDistance": "Search By Distance", "searchByMinimumRatings": "Search By Minimum Ratings", -"chat": "Chat", + "chat": "Chat", "noRequestsShow": "No Requests to show.", "typeMessageHere": "Type your message here..", "reject": "Reject", @@ -561,7 +561,7 @@ "termPrivacy": "Term & Privacy", "inviteFriends": "Invite Friends", "more": "More", - "language" :"Language", + "language": "Language", "mySubscriptions": "My Subscription", "subscriptions": "Subscriptions", "defineLicenses": "Define Licenses", @@ -571,14 +571,15 @@ "amountVAR": "Amount", "requestAlreadyInProgress": "This request is already in progress.", "acceptOfferConfirmation": "Do you want to accept this offer?", - "acceptOfferConfirmationMessage": "This offer will be accepted and you will pay the requested amount to the buyer in given time or else this offer will be cancelled." + "acceptOfferConfirmationMessage": "This offer will be accepted and you will pay the requested amount to the buyer in given time or else this offer will be cancelled.", "nowVar": "Now", "whendoyouWanttoUpgrade": "When do you want to upgrade", "yourSubscriptionUpgradeAffectingFrom": "Your subscription will upgrade now. Affecting from", "upgradeAfterCurrentExpiry": "Upgrade after current expiry", "yourSubscriptionUpgradeCurrentSubscriptionAffectingFrom": "Your subscription will upgrade after you current subscription will end. Affecting from", "upgradeVar": "Upgrade", - "whendoyouWanttoRenew" : "When do you want to renew", - "renewVar" : "Renew", - + "whendoyouWanttoRenew": "When do you want to renew", + "renewVar": "Renew", + "noUpcomingAppointments": "No Upcoming Appointment Available.", + "addNewAppointment": "Add New Appointment" } \ No newline at end of file diff --git a/lib/classes/app_state.dart b/lib/classes/app_state.dart index adb79fc..2b1d974 100644 --- a/lib/classes/app_state.dart +++ b/lib/classes/app_state.dart @@ -25,6 +25,14 @@ class AppState { _deviceToken = value; } + String? _deviceType; + + String? get getDeviceType => _deviceType; + + set setDeviceType(String value) { + _deviceType = value; + } + AppType currentAppType = AppType.provider; UserType userType = UserType.customer; diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index b41d2b4..500f758 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -156,8 +156,11 @@ class ApiConsts { //Chat static String chatHubUrl = "$baseUrlServices/McHub"; - static String messageIsReadUpdate = "${baseUrlServices}api/RequestManagement/ReqOfferChatIsRead_Update"; - static String getChatMessages = "${baseUrlServices}api/RequestManagement/ReqOfferChat_Get"; + static String messageIsReadUpdateForRequests = "${baseUrlServices}api/RequestManagement/ReqOfferChatIsRead_Update"; + static String messageIsReadUpdateForAds = "${baseUrlServices}api/Advertisement/AdsChatIsRead_Update"; + static String getChatMessagesForRequests = "${baseUrlServices}api/RequestManagement/ReqOfferChat_Get"; + static String getChatMessagesForAds = "${baseUrlServices}api/Advertisement/AdsChat_Get"; + static String getChatBuyersForAds = "${baseUrlServices}api/Advertisement/AdsChatBuyer_Get"; static List closingUrls = ["PayFortResponse"]; } @@ -298,7 +301,6 @@ class MyFonts { } class SignalrConsts { - // Requests static String receiveMessageRequestOffer = "ReceiveMessageRequestOffer"; static String sendMessageRequestOffer = "SendMessageRequestOffer"; diff --git a/lib/config/routes.dart b/lib/config/routes.dart index 0441cd8..8ef24cb 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -1,14 +1,24 @@ import 'package:mc_common_app/models/advertisment_models/ad_details_model.dart'; -import 'package:mc_common_app/models/requests_models/offers_model.dart'; +import 'package:mc_common_app/models/chat_models/buyers_chat_for_ads_model.dart'; import 'package:mc_common_app/models/requests_models/provider_offers_model.dart'; import 'package:mc_common_app/models/requests_models/request_model.dart'; import 'package:mc_common_app/models/user_models/register_user.dart'; import 'package:mc_common_app/utils/enums.dart'; +import 'package:mc_common_app/views/advertisement/ads_buyer_chats_list_view.dart'; +import 'package:mc_common_app/views/advertisement/ads_detail_view.dart'; +import 'package:mc_common_app/views/advertisement/ads_filter_view.dart'; +import 'package:mc_common_app/views/advertisement/create_ad_view.dart'; +import 'package:mc_common_app/views/advertisement/select_ad_type_view.dart'; +import 'package:mc_common_app/views/chat/chat_view.dart'; +import 'package:mc_common_app/views/payments/payment_methods_view.dart'; import 'package:mc_common_app/views/profile/profile_view.dart'; +import 'package:mc_common_app/views/requests/create_request_page.dart'; +import 'package:mc_common_app/views/requests/offer_list_page.dart'; import 'package:mc_common_app/views/setting_options/provider_license_page.dart'; import 'package:mc_common_app/views/setting_options/setting_option_help.dart'; +import 'package:mc_common_app/views/setting_options/setting_options_faqs.dart'; +import 'package:mc_common_app/views/setting_options/setting_options_invite_friends.dart'; import 'package:mc_common_app/views/setting_options/setting_options_language.dart'; - import 'package:mc_common_app/views/user/change_email_page.dart'; import 'package:mc_common_app/views/user/change_mobile_page.dart'; import 'package:mc_common_app/views/user/change_password_page.dart'; @@ -67,6 +77,7 @@ class AppRoutes { static const String adsDetailView = "/adsDetailView"; static const String createAdView = "/createAdView"; static const String adsFilterView = "/adsFilterView"; + static const String adsBuyerChatsListView = "/adsBuyersChatListView"; // Payments static const String paymentMethodsView = "/paymentMethodsView"; @@ -116,28 +127,12 @@ class AppRoutes { forgetPassword: (context) => const ForgetPasswordPage(), loginVerification: (context) => const LoginVerificationPage(), loginWithPassword: (context) => const LoginWithPassword(), - loginMethodSelection: (context) => - LoginMethodSelectionPage(ModalRoute - .of(context)! - .settings - .arguments as String), - completeProfile: (context) => - CompleteProfilePage(ModalRoute - .of(context)! - .settings - .arguments as RegisterUserRespModel), + loginMethodSelection: (context) => LoginMethodSelectionPage(ModalRoute.of(context)!.settings.arguments as String), + completeProfile: (context) => CompleteProfilePage(ModalRoute.of(context)!.settings.arguments as RegisterUserRespModel), verifyPassword: (context) => VerifyPasswordPage(), - confirmNewPasswordPage: (context) => - ConfirmNewPasswordPage(ModalRoute - .of(context)! - .settings - .arguments as String), + confirmNewPasswordPage: (context) => ConfirmNewPasswordPage(ModalRoute.of(context)!.settings.arguments as String), changePassword: (context) => const ChangePasswordPage(), - forgetPasswordMethodPage: (context) => - ForgetPasswordMethodPage(ModalRoute - .of(context)! - .settings - .arguments as String), + forgetPasswordMethodPage: (context) => ForgetPasswordMethodPage(ModalRoute.of(context)!.settings.arguments as String), changeMobilePage: (context) => ChangeMobilePage(), changeEmailPage: (context) => const ChangeEmailPage(), editAccountPage: (context) => const EditAccountPage(), @@ -145,6 +140,19 @@ class AppRoutes { settingOptionsLanguages: (context) => const SettingOptionsLanguage(), settingOptionsHelp: (context) => const SettingOptionsHelp(), providerLicensePage: (context) => ProviderLicensePage(), + + // common pages + AppRoutes.adsDetailView: (context) => AdsDetailView(adDetails: ModalRoute.of(context)!.settings.arguments as AdDetailsModel), + AppRoutes.createAdView: (context) => const CreateAdView(), + AppRoutes.adsFilterView: (context) => const AdsFilterView(), + AppRoutes.selectAdTypeView: (context) => SelectAdTypeView(isProvider: ModalRoute.of(context)!.settings.arguments as bool), + AppRoutes.chatView: (context) => ChatView(chatViewArguments: ModalRoute.of(context)!.settings.arguments as ChatViewArguments), + AppRoutes.offersListPage: (context) => OfferListPage(offerListPageArguments: ModalRoute.of(context)!.settings.arguments as OfferListPageArguments), + AppRoutes.adsBuyerChatsListView: (context) => AdsBuyerChatsListView(buyersListViewArguments: ModalRoute.of(context)!.settings.arguments as List), + AppRoutes.createRequestPage: (context) => const CreateRequestPage(), + AppRoutes.settingOptionsFaqs: (context) => const SettingOptionsFAQs(), + AppRoutes.settingOptionsInviteFriends: (context) => const SettingOptionsInviteFriends(), + AppRoutes.paymentMethodsView: (context) => PaymentMethodsView(paymentType: ModalRoute.of(context)!.settings.arguments as PaymentTypes), }; } @@ -169,9 +177,10 @@ class ChatViewArgumentsForRequest { } class ChatViewArgumentsForAd { - final AdDetailsModel? adDetailsModel; + final String? receiverUserID; + final int? adsID; - ChatViewArgumentsForAd({required this.adDetailsModel}); + ChatViewArgumentsForAd({required this.receiverUserID, required this.adsID}); } class ChatViewArguments { diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index 9d007bd..8913904 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -234,6 +234,9 @@ extension AppointmentStatusToInt on AppointmentStatusEnum { case AppointmentStatusEnum.visitCompleted: return 8; + case AppointmentStatusEnum.allAppointments: + return 0; + default: return 0; } diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index 1413bb5..d52c675 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -6,7 +6,7 @@ import 'dart:ui'; import 'package:easy_localization/easy_localization.dart' show AssetLoader; -class CodegenLoader extends AssetLoader { +class CodegenLoader extends AssetLoader{ const CodegenLoader(); @override @@ -14,1124 +14,1174 @@ class CodegenLoader extends AssetLoader { return Future.value(mapLocales[locale.toString()]); } - static const Map ar_SA = { - "firstTimeLogIn": "تسجيل الدخول لأول مره", - "signUp": "التسجيل", - "changeMobile": "تغيير رقم الجوال", - "notifications": "الاشعارات", - "general": "عام", - "defineLicences": "تحديد الرخص", - "dealershipSettings": "اعدادات البيع", - "changePassword": "تغيير كلمة المرور", - "retrievePassword": "استرجاع كلمة المرور", - "changeEmail": "تغيير الايميل", - "verify": "تحقق", - "verified": "تم التحقق", - "signOut": "تسجيل خروج", - "enterEmail": "ادخل الايميل", - "enterNewEmail": "ادخل ايميل جديد", - "enterCurrentPassword": "كلمة المرور الحاليه", - "enterNewPassword": "كلمة المرور الجديده", - "enterOldPassword": "كلمة المرور القديمه", - "confirm": "تأكيد", - "enterNewPhoneNumber": "رقم جوال جديد", - "completeProfile": "الملف الشخصي", - "continu": "استمرار", - "confirmPassword": "تأكيد كلمة المرور", - "createPassword": "انشاء كلمة مرور جديده", - "email": "ايميل", - "firstName": "الأسم الأول *", - "surname": "اسم العائله *", - "confirmPass": "تأكيد كلمة المرور *", - "createPass": "انشاء كلمة مرور جديده *", - "newPassword": " كلمة مرور جديده", - "forgetPassword": "نسيت كلمة المرور", - "forgetPasswordRecover": "نسيت كلمة المرور؟ استعادة", - "editAccount": "تعديل الحساب", - "change": "تغيير", - "verifyAccount": "التحقق من الحساب", - "login": "تسجيل دخول", - "welcomeMessage": "مرحبا", - "forgetPass": "نسيت كلمة المرور ؟", - "enterPhoneNumber": "رقم جوال ", - "phoneNumberVerified": "تم التحقق من الجوال", - "verifyNewPassword": "التحقق من كلمة المرور", - "EnterPass": "ادخل كلمة المرور", - "alreadySigned": " تم تسجيل الدخول", - "emailChangedSuccessfully": "تم تغيير الايميل بنجاح", - "passwordIsUpdated": "تم تحجيث كلمة المرور", - "passwordShouldContains": "كلمة المرور يجب ان تحتوي على رمز رقم حرف كبير حرف صغير", - " successfullyRegistered": "تم التسجيل بنجاح", - "pleaseEnterSamePassword": "ادخل كلمة مرور مطابقه", - "firstNameMandatory": "ادخل الأسم الأول ", - "surnameNameMandatory": "ادخل اسم العائله", - "passwordNameMandatory": "ادخل كلمة المرور", - "enterValidEmail": "ادخل ايميل صحيح", - "pleaseAcceptTerms": "يجب الموافقه على الشروط", - "emailVerified": "تم التحقق من الايميل بنجاح", - "selectMethod": "اختر", - "emailAddress": "ايميل", - "loginSelection": "اختر", - "selectCountryCode": "اختر رمز الدوله", - "selectProviderRole": "اختر نوع الخدمه", - "addPhoneNo": "اضف الهاتف", - "onlyCustomerApp": "نأسف هذا التطبيق فقط للعملاء", - "imageUploaded": "تم تحميل الصوره", - "fileLarger": "1KB حجم الملف اكبر من", - "account": "الحساب", - "edit": "تعديل", - "imageDeleted": "تم حذف الصوره", - "dashboard": "الصفحه الرئيسيه", - "termsOfService": "من خلال إنشاء حساب فإنك توافق على", - "userInformation": "معلومات المتسخدم", - "faceRecognition": "تحقق مع بصمة الوجه", - "fingerPrint": "تحقق مع بصمة الاصبع", - "whatsapp": "تحقق مع Whatsapp", - "SMS": "رسائل قصيره", - "selectRole": "حدد الدور", - "userRoleOrTitle": "عنوان المستخدم", - "codeSentToEmail": "تم ارسال الرمز للايميل", - "number": "موبايل", - "english": "عربي", - "title": "مرحبًا", - "msg": "Hello {} in the {} world ", - "msg_named": "{} are written in the {lang} language", - "clickMe": "انقر فوق لي", - "profile": { - "reset_password": {"label": "إعادة تعيين كلمة المرور", "username": "اسم المستخدم", "password": "كلمة المرور"} - }, - "clicked": { - "zero": "You clicked {} times!", - "one": "You clicked {} time!", - "two": "You clicked {} times!", - "few": "You clicked {} times!", - "many": "You clicked {} times!", - "other": "You clicked {} times!" - }, - "amount": {"zero": "Your amount : {} ", "one": "Your amount : {} ", "two": "Your amount : {} ", "few": "Your amount : {} ", "many": "Your amount : {} ", "other": "Your amount : {} "}, - "gender": { - "male": "Hi man ;) ", - "female": "Hello girl :)", - "with_arg": {"male": "Hi man ;) {}", "female": "Hello girl :) {}"} - }, - "reset_locale": "إعادة ضبط اللغة", - "welcomeDes": "أنت مكان واحد لكل ما تحتاجه سيارتك", - "log_in": "تسجيل الدخول", - "send": "إرسال", - "phoneNumber": "رقم الهاتف", - "forgetPasswordQ": "نسيت كلمة المرور؟", - "recover": "استعادة", - "retrivePassword": "استرجع كلمة المرور بإحدى الطرق التالية", - "retriveOnPhone": "سوف نرسل الاختيار إلى رقم هاتفك المحمول المسجل", - "retriveOnEmail": "سوف نرسل الاختيار إلى عنوان بريدك الإلكتروني المسجل", - "enterPhoneForVerfication": "الرجاء إدخال رقم هاتفك وسنرسل لك رمز التحقق", - "welcomeBack": "مرحبًا بعودتك!!!", - "selectYourCountry": "اختر بلدك", - "chooseCountry": "اختر الدوله", - "terms": "بنود الخدمة وخصوصية السياسة", - "profileMsg": "أدخل التفاصيل أدناه وأكمل معلومات الملف الشخصي", - "save": "حفظ", - "insert_otp_code": "ادخل الرمز", - "type_code": "الرجاء كتابة الرمز الذي أرسلناه إلى", - "resend_code": "أعد إرسال الرمز", - "check_code": "التحقق من الشفرة", - "time_will_expire": "إعادة إرسال الرمز بتنسيق", - "sec": "ثانية", - "providers": "الموفرون", - "appointments": "تعيينات", - "home": "بيت", - "ads": "إعلانات", - "settings": "إعدادات", - "view_all": "مشاهدة الكل", - "my_active_Ads": "إعلاناتي النشطة", - "recommended_ads": "الإعلانات الموصى بها", - "upcoming_appointment": "الموعد القادم", - "my_service_providers": "مزودي الخدمة الجدد", - "appointment_details": "تفاصيل الموعد", - "no_city_available": "لا توجد مدينة متاحة لهذا البلد", - "branch_created": "تم إنشاء الفرع بنجاح", - "branch_updated": "تم تحديث الفرع بنجاح", - "branch_deleted": "تم حذف الفرع بنجاح", - "dashboard_main": "لوحة القيادة / الصفحة الرئيسية", - "logo_brand": "الشعار / العلامة التجارية", - "remove": "إزالة", - "no_branch": "لم يتم إضافة فرع حتى الآن", - "login_once": "الرجاء تسجيل الدخول مرة واحدة", - "defineLicenese": "تحميل التراخيص والشهادات", - "description": "وصف", - "attachFile": "أرفق ملف", - "branchLocation": "معلومات الفرع والموقع", - "tapToEdit": "انقر للتعديل", - "myServiceBranches": "فروع خدمتي", - "enter_licence_detail": "الرجاء إدخال تفاصيل السجلات التجارية وإرفاق صور الترخيص", - "country": "بلد", - "city": "مدينة", - "editServices": "تحرير الخدمات", - "maintenance": "صيانة", - "accessories_modifications": "الملحقات والتعديلات", - "my_recent_providers": "مزودي الخدمة الجدد", - "my_active_ads": "إعلاناتي النشطة", - "recommended_Ads": "الإعلانات الموصى بها", - "location": "موقع", - "address": "عنوان", - "branchName": "اسم الفرع", - "branchDescription": "وصف الفرع", - "branchInfo": "معلومات الفرع", - "defineServices": "تحديد الخدمات", - "defineBranches": "تحديد الفروع", - "defineProviders": "تحديد الموفرين", - "closeAccount": "حساب مغلق", - "selectServiceCategory": "حدد فئة الخدمة", - "selectService": "حدد الخدمة", - "selectBranch": "حدد الفرع", - "createBranch": "إنشاء فرع", - "updateBranch": "تحديث فرع", - "branches": "الفروع", - "requests": "الطلبات", - "noBranchFound": "لم يتم العثور على فرع", - "onlyProviderApp": "نأسف هذا التطبيق فقط لمقدمي الخدمات", - "pickAddress": "اختر العنوان", - "pickLocation": "اختر الموقع", - "chooseCity": "اختر المدينه", - "selectAttachment": "اختيار مرفق", - "somethingWrong": "هناك خطأ ما", - "documentsUploaded": "تم ارفاق الملف بنجاح", - "update": "تحديث", - "profileCompleted": "الملف الشخصي مكتمل", - "selectLocationMap": "اختر الموقع", - "licensesAndCertifications": "الرخص و الشهادات", - "completeProfile1": "اكمل الملف الشخصي 1/3", - "completeProfile2": "اكمل الملف الشخصي 2/3", - "completeProfile3": "اكمل الملف الشخصي 3/3", - "provider": "مزود", - "noRequeststoShow": "لا توجد طلبات للعرض", - "myBranches": "فروعي", - "mergeAppointments": "دمج المواعيد", - "addService": "أضف الخدمة", - "selectServicestoAdd": "حدد الخدمات التي تريد إضافتها", - "noServiceFound": "لم يتم العثور على الخدمة", - "selectItems": "اختيار العناصر", - "noItemSelectedYet": "لم يتم تحديد أي عنصر بعد", - "totalAdditionalAmount": "إجمالي المبلغ الإضافي", - "sar": "ريال سعودي", - "cancel": "يلغي", - "add": "يضيف", - "itemsAddedSuccessfully": "تمت إضافة العناصر بنجاح", - "pleaseSelectItems": "يرجى اختيار العناصر", - "totalAmount": "المبلغ الإجمالي", - "searchItems": "البحث عن العناصر", - "addSelectedItems": "إضافة العناصر المحددة", - "collectMoneyBefore": "هل ترغب في جمع المال قبل تقديم الخدمات؟", - "yes": "نعم", - "no": "لا", - "reason": "السبب", - "typeHere": "اكتب هنا...", - "pleaseSelectReason": "يرجى تحديد السبب", - "noAppointmentFound": "لم يتم العثور على مواعيد", - "slotsOverview": "نظرة عامة على الفتحات", - "empty": "فارغ", - "occupied": "محجوز", - "totalSlots": "إجمالي الفتحات", - "selectAppointments": "اختيار المواعيد", - "appointmentMergeSuccessfully": "دمج المواعيد تم بنجاح", - "updateAppointment": "تحديث الموعد", - "addNewService": "إضافة خدمة جديدة", - "waitingPaymentfromtheCustomer": "في انتظار الدفع من العميل", - "appointmentisCompleted": "تم اكتمال الموعد", - "workStart": "بدء العمل", - "payNow": "ادفع الآن", - "arrived": "وصل", - "payLater": "ادفع لاحقًا", - "complete": "اكتمل", - "makeAnOffer": "قدم عرضًا", - "enterAmount": "أدخل المبلغ", - "submit": "إرسال", - "viewChat": "عرض الدردشة", - "requestDetail": "تفاصيل الطلب", - "sendOffer": "إرسال عرض", - "offer": "عرض", - "sendPriceOffer": "إرسال عرض السعر", - "comment": "تعليق", - "sendOTP": "إرسال رمز OTP", - "noUserAddedYet": "لم يتم إضافة مستخدم بعد", - "assignDealerUser": "تعيين مستخدم تاجر", - "createNewUser": "إنشاء مستخدم جديد", - "dealerUser": "مستخدم تاجر", - "setorEditBranchSchedule": "تعيين أو تحرير جدول الفروع", - "addServices": "إضافة خدمات", - "noServiceAddedYet": "لم تتم إضافة خدمات بعد", - "selectDays": "اختيار الأيام", - "addSelectedDays": "إضافة الأيام المحددة", - "select_Services": "اختيار الخدمات", - "searchService": "البحث عن الخدمة", - "addSelectedServices": "إضافة الخدمات المحددة", - "nameofSchedule": "اسم الجدول الزمني", - "startingDate": "تاريخ البدء", - "endDate": "تاريخ الانتهاء", - "offDays": "أيام الراحة", - "shiftStartTime": "وقت بدء الوردية", - "shiftEndTime": "وقت انتهاء الوردية", - "slotsTime": "وقت الفتحات", - "appointmentPerSlot": "موعد لكل فتحة", - "create": "إنشاء", - "pleaseEnterValidScheduleName": "يرجى إدخال اسم جدول صالح", - "pleaseSelectServices": "يرجى اختيار الخدمات", - "pleaseSelectStartDate": "يرجى تحديد تاريخ البدء", - "pleaseSelectEndDate": "يرجى تحديد تاريخ الانتهاء", - "pleaseSelectOffDays": "يرجى تحديد أيام الراحة", - "pleaseSelectStartTime": "يرجى تحديد وقت بدء الوردية", - "pleaseSelectEndTime": "يرجى تحديد وقت انتهاء الوردية", - "pleaseSelectSlotTime": "يرجى تحديد وقت الفتحة", - "pleaseSelectAppointmentPerSlot": "يرجى تحديد موعد لكل فتحة", - "exploreAds": "استكشاف الإعلانات", - "myAds": "إعلاناتي", - "noAppointmentstoShow": "لا توجد مواعيد لعرضها", - "myRecommendedAds": "الإعلانات الموصى بها لي", - "model": "الموديل", - "chooseImageSource": "اختر مصدر الصورة", - "camera": "الكاميرا", - "gallery": "المعرض", - "imageIsDeleted": "تم حذف الصورة", - "myRequests": "طلباتي", - "branchDetail": "تفاصيل الفرع", - "time": "الوقت", - "openMapLocation": "فتح موقع الخريطة", - "providerProfile": "ملف المزود", - "servicesOffer": "الخدمات المقدمة", - "noServicesAvailable": "لا تتوفر خدمات", - "bookAppointment": "حجز موعد", - "allowingHomeService": "السماح بخدمة منزلية", - "homeServiceRange": "نطاق الخدمة المنزلية", - "chargesPerKM": "الرسوم لكل كيلومتر", - "providerDetails": "تفاصيل المزود", - "someDescriptionExperienceandtheirReputation": "بعض الوصف عن المزود وسنوات خبرتهم وسمعتهم", - "availableforAppointment": "متاح للموعد", - "allowingWorkshopService": "السماح بخدمة ورشة العمل", - "serviceAmount": "مبلغ الخدمة", - "youNeedStoragePermissionFiles": "تحتاج إلى منح إذن التخزين لاختيار الملفات.", - "settingDeniedPermanently": "تم رفض هذا الإذن بشكل دائم، يرجى الذهاب إلى الإعدادات والسماح.", - "openAppSetting": "افتح إعدادات التطبيق", - "adDuration": "مدة الإعلان", - "startDate": "تاريخ البدء", - "contactDetails": "تفاصيل الاتصال", - "showyournumbertoBuyers": "هل تريد إظهار رقمك للمشترين؟", - "isNumberRegisteredWhatsApp": "هل هذا الرقم مسجل على واتساب؟", - "selectSpecialServices": "اختر الخدمات الخاصة", - "vehicleDetails": "تفاصيل المركبة", - "vehicleModel": "طراز المركبة", - "vehicleColor": "لون المركبة", - "vehicleCategory": "فئة المركبة", - "vehicleTransmission": "نقل المركبة", - "vehicleCountry": "بلد المركبة", - "vehicleAmount": "مبلغ المركبة", - "vehicleTitle": "عنوان المركبة", - "financeAvailable": "التمويل متاح", - "vehiclePictures": "صور المركبة", - "vehiclePart": "جزء المركبة", - "damagePartPictures": "صور الأجزاء المتضررة", - "vehicleDamagePart": "جزء المركبة المتضرر", - "duration": ":المدة", - "specialServices": "الخدمات الخاصة", - "specialService": "خدمة خاصة", - "adContactDetails": "تفاصيل الاتصال بالإعلان", - "onWhatsAp": "على واتساب", - "reserveAdPriceInfo": "معلومات سعر الإعلان المحجوز", - "addDamagePart": "إضافة جزء متضرر", - "vehicleType": "نوع المركبة", - "vehicleYear": "سنة المركبة", - "vehicleCondition": "حالة المركبة", - "vehicleMileage": "عدد الأميال للمركبة", - "sellerType": "نوع البائع", - "vehicleCity": "مدينة المركبة", - "vehicleVIN": "رقم تعريف المركبة (VIN)", - "warrantyAvailable": "الضمان متاح", - "years": "سنوات", - "vehicleDetail": "تفاصيل المركبة", - "vehicleBrand": "ماركة المركبة", - "vehicleModelYear": "سنة طراز المركبة", - "vehicleSellerType": "نوع بائع المركبة", - "demandAmount": "المبلغ المطلوب", - "warrantyAvailableYears": "الضمان متاح (عدد السنوات)", - "vehicleDescription": "وصف المركبة", - "attachImage": "إرفاق صورة", - "useFingerPrintFaceID": "يرجى استخدام بصمة الإصبع أو معرف الوجه", - "setupTouchID": "يرجى إعداد معرف اللمس", - "reenableTouchID": "يرجى إعادة تمكين معرف اللمس", - "scanFaceIDAuthenticate": "امسح بصمة الإصبع أو معرف الوجه للتحقق", - "AdDeletedSuccessfully": "تم حذف الإعلان بنجاح!", - "yourReservationCancelled": "تم إلغاء حجزك.", - "adDeactivatedSuccessfully": "تم إلغاء تفعيل الإعلان بنجاح!", - "vehicle": { - "selectVehicleType": "يرجى اختيار نوع السيارة", - "selectVehicleModel": "يرجى اختيار طراز السيارة", - "selectVehicleModelYear": "يرجى اختيار سنة طراز السيارة", - "selectVehicleColor": "يرجى اختيار لون السيارة", - "vehicleCondition": "يرجى اختيار حالة السيارة", - "vehicleCategory": "يرجى اختيار فئة السيارة", - "vehicleMileage": "يرجى اختيار عدد أميال السيارة", - "vehicleTransmission": "يرجى اختيار نوع ناقل الحركة", - "vehicleSellerType": "يرجى اختيار نوع بائع السيارة", - "selectAny": "يرجى اختيار أي خيار", - "vehicleCity": "يرجى اختيار مدينة السيارة", - "vehiclePart": "يرجى اختيار جزء السيارة", - "selectValidVehicleType": "يرجى اختيار نوع سيارة صالح" - }, - "selectAppointmentTimeService": "يجب عليك اختيار وقت الموعد للخدمة.", - "error": "خطأ", - "appointmentBookedSuccessfully": "تم حجز موعدك بنجاح", - "appointmentStatusUpdated": "تم تحديث حالة الموعد", - "paymentStatusUpdated": "تم تحديث حالة الدفع", - "selectOneSubService": "يرجى اختيار خدمة فرعية واحدة على الأقل", - "chargesBreakdown": "تفاصيل الرسوم", - "services": "الخدمات", - "homeLocation": "الموقع المنزلي", - "selectAppointmentTime": "يجب عليك اختيار وقت الموعد لكل موعد في الجدول", - "noAppointmentAvailable": "لا توجد مواعيد متاحة للعناصر المحددة", - "changedMind": "لقد غيرت رأيي", - "veryHighPrice": "السعر مرتفع جداً", - "alreadySold": "تم البيع بالفعل", - "otherVar": "أخرى", - "paymentSuccessful": "تم الدفع بنجاح", - "paymentFailed": "فشل الدفع!", - "requestSuccessfullyCreated": "تم إنشاء الطلب بنجاح", - "selectValidRequestType": "يرجى اختيار نوع طلب صالح", - "selectValidBrand": "يرجى اختيار علامة تجارية صالحة", - "selectValidModel": "يرجى اختيار طراز صالح", - "selectValidYear": "يرجى اختيار سنة صالحة", - "selectValidCountry": "يرجى اختيار بلد صالح", - "selectValidCity": "يرجى اختيار مدينة صالحة", - "addValidPrice": "يرجى إضافة سعر صالح", - "addValidDescription": "يرجى إضافة وصف صالح", - "passwordTooShort": "كلمة المرور الخاصة بك قصيرة جدًا", - "passwordAcceptableStrong": "كلمة المرور الخاصة بك مقبولة ولكنها ليست قوية", - "passwordIsStrong": "كلمة المرور الخاصة بك قوية", - "passwordVeryStrong": "كلمة المرور الخاصة بك قوية جدًا", - "selectDuration": "اختر المدة", - "daysVar": "الأيام", - "adCharges": "رسوم الإعلان", - "select": "اختر", - "deleteAdConfirmation": "هل تريد حذف الإعلان؟", - "deleteAdConfirmationMessage": "سيتم حذف إعلانك نهائيًا ولا يمكنك التراجع عن هذا الإجراء", - "mileage": "المسافة المقطوعة", - "transmission": "ناقل الحركة", - "demand": "الطلب", - "adDurationExpired": "انتهت مدة عرض الإعلان الخاص بك", - "bankDetails": "تفاصيل البنك", - "bankName": "اسم البنك", - "iban": "الرقم الدولي للحساب المصرفي (IBAN)", - "rejectionComments": "تعليقات الرفض", - "editAd": "تعديل الإعلان", - "reserveAd": "حجز الإعلان", - "reservationAmount": "مبلغ الحجز", - "belowAmountPayLater": "المبلغ الذي ستدفعه لاحقًا", - "carPrice": "سعر السيارة", - "vatExcluded": "القيمة المضافة غير مشمولة", - "carInsuranceService": "خدمة التأمين على السيارة", - "toBeDecided": "لم يتم اتخاذ القرار بعد", - "registrationCarPlates": "تسجيل ولوحات السيارة", - "homeDeliveryService": "خدمة التوصيل إلى المنزل", - "specialServicechargesInsuranceDeliveryLocation": "سيتم إضافة رسوم خدمة خاصة بناءً على التأمين المطلوب وموقع التسليم", - "estimated": "مقدر", - "servicesReservingAd": "بعض الخدمات إلزامية أثناء حجز الإعلان", - "completeReservation": "إتمام الحجز", - "contact": "اتصال", - "setDateandTime": "تحديد التاريخ والوقت", - "selectOffice": "اختيار المكتب", - "availableSlots": "المواعيد المتاحة", - "bookAndPay": "الحجز والدفع", - "reservationAmounts": "مبالغ الحجز", - "tax": "الضريبة", - "adsFilter": "تصفية الإعلانات", - "searchByCity": "البحث حسب المدينة", - "selectCity": "اختر المدينة", - "searchByBrandName": "البحث حسب اسم العلامة التجارية", - "selectVehicleBrand": "اختر علامة تجارية للسيارة", - "searchByVehicleYear": "البحث حسب سنة السيارة", - "selectYear": "اختر السنة", - "searchByAdOwner": "البحث حسب مالك الإعلان", - "selectOwner": "اختر المالك", - "search": "بحث", - "clearFilters": "مسح التصفية", - "book": "حجز", - "markAsSold": "وضع علامة تم البيع", - "deactivateAd": "إلغاء تفعيل الإعلان", - "doWantDeactivateAd": "هل تريد إلغاء تفعيل هذا الإعلان؟", - "stoptheBuyers": "سنتوقف عن عرض هذا الإعلان للمشترين", - "cancelReservation": "إلغاء الحجز", - "reasonForCancellation": "سبب الإلغاء", - "doWantCancelReservation": "هل تريد إلغاء الحجز؟", - "yourAdVisibletoBuy": "سيتم إلغاء حجز إعلانك وسيكون هذا الإعلان مرئيًا للجميع مرة أخرى للشراء", - "completeDeal": "إتمام الصفقة", - "uploadBankReceipt": "تحميل إيصال البنك", - "notesForAdmin": "ملاحظات للإدارة", - "extendAd": "تمديد الإعلان", - "updateAdDetails": "هل تريد تحديث تفاصيل الإعلان", - "durationExtendingAd": "يمكنك تغيير مدة الإعلان والتفاصيل قبل تمديد الإعلان", - "waitingAdminsResponse": "في انتظار رد الإدارة", - "cancelledByOwner": "ألغيت من قبل المالك", - "cancelledByAdmin": "ألغيت من قبل الإدارة", - "reservationTimeOver": "انتهى وقت الحجز", - "paymentVerified": "تم التحقق من الدفع", - "rejectedFormAdmin": "تم الرفض من قبل الإدارة", - "waitingAdminPost": "في انتظار الإدارة للنشر", - "waitingAdminsApproval": "في انتظار موافقة الإدارة", - "sold": "تم البيع", - "noAdsShow": "لا توجد إعلانات لعرضها", - "damagePartList": "قائمة الأجزاء المتضررة", - "searchPart": "البحث عن جزء", - "addSpecialService": "إضافة خدمة خاصة", - "vehicleVar": "السيارة", - "detailsVar": "التفاصيل", - "damageVar": "الضرر", - "partsVar": "الأجزاء", - "additional": "إضافي", - "review": "مراجعة", - "adVar": "الإعلان", - "updateAd": "تحديث الإعلان", - "createAd": "إنشاء إعلان", - "next": "التالي", - "submitAd": "إرسال الإعلان", - "selectAdType": "اختر نوع الإعلان", - "validUntilSubscriptionExpiration": "صالح حتى انتهاء الاشتراك", - "adsRemainingVar": "الإعلانات المتبقية", - "youLeftAdsGivenSubscription": "لقد بقي لديك 05 من 50 إعلانًا في الاشتراك.", - "updateSubscription": "تحديث الاشتراك", - "workInProgress": "العمل جارٍ", - "visitCompleted": "تمت الزيارة", - "youWantCancelAppointment": "هل تريد إلغاء هذا الموعد؟", - "appointmentCancelledCannotUndoAction": "سيتم إلغاء موعدك ولا يمكنك التراجع عن هذا الإجراء", - "appointment": "الموعد", - "rescheduleAppointment": "إعادة جدولة الموعد", - "payforAppointment": "دفع ثمن الموعد", - "appointmentsFilter": "تصفية المواعيد", - "searchByProvider": "البحث حسب المزود", - "selectProvider": "اختر المزود", - "searchByBranch": "البحث حسب الفرع", - "searchByCategory": "البحث حسب الفئة", - "selectCategory": "اختر الفئة", - "searchByService": "البحث حسب الخدمة", - "selectServices": "اختر الخدمات", - "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": "اللغة", - "mySubscription": "اشتراكاتي", - "subscriptions": "الاشتراكات", - "defineLicenses": "تحديد التراخيص", - "logOut": "تسجيل الخروج", - "customer": "العميل", - "amountVAR": "كمية", - "accept": "قبول", - "requestAlreadyInProgress": "هذا الطلب قيد التقدم بالفعل.", - "acceptOfferConfirmation": "هل تريد قبول هذا العرض؟", - "acceptOfferConfirmationMessage": "سيتم قبول هذا العرض وستدفع المبلغ المطلوب للمشتري في وقت معين وإلا سيتم إلغاء هذا العرض." - }; - static const Map en_US = { - "firstTimeLogIn": "First Time Log In", - "signUp": "Sign Up", - "changeMobile": "Change Mobile", - "notifications": "Notifications", - "general": "General", - "defineLicences": "Define Licences", - "dealershipSettings": "Dealership Settings", - "changePassword": "Change Password", - "retrievePassword": "Retrieve Password", - "changeEmail": "Change Email", - "verify": "Verify", - "verified": "Verified", - "signOut": "Sign Out", - "enterEmail": "Enter Email", - "enterNewEmail": "Enter New Email", - "enterNewPassword": "Enter New Password", - "enterCurrentPassword": "Enter Current Password", - "enterOldPassword": "Enter Old Password", - "confirm": "Confirm", - "completeProfile": "Complete Profile", - "enterNewPhoneNumber": "Enter New Phone Number", - "enterPhoneNumber": "Enter Phone Number", - "continu": "Continue", - "confirmPassword": "Confirm Password", - "createPassword": "Create Password", - "email": "Email", - "firstName": "First Name *", - "surname": "Surname *", - "confirmPass": "Confirm Password *", - "createPass": "Create Password *", - "newPassword": "New Password", - "forgetPassword": "Forget Password", - "forgetPasswordRecover": "Forget Password? Recover", - "editAccount": "Edit Account", - "change": "Change", - "verifyAccount": "Verify Account", - "login": "Log In", - "welcomeMessage": "Welcome Message", - "forgetPass": "Forget Password ?", - "phoneNumberVerified": "Phone Number Verified", - "verifyNewPassword": "Verify New Password", - "EnterPass": "Enter Password ?", - "alreadySigned": " Already Signed Up and Logged In", - "emailChangedSuccessfully": "Email is Changed Successfully", - "passwordIsUpdated": "Password is Updated", - "passwordShouldContains": "Password Should contains Character, Number, Capital and small letters,", - " successfullyRegistered": " Successfully Registered, Please login once,", - "pleaseEnterSamePassword": "Please enter same password", - "firstNameMandatory": "First name is mandatory", - "surnameNameMandatory": "Surname is mandatory", - "passwordNameMandatory": "Password is mandatory", - "enterValidEmail": "Enter Valid Email", - "pleaseAcceptTerms": "Please accept terms", - "emailVerified": "Email is verified successfully", - "selectMethod": "Select Method", - "emailAddress": "Email Address", - "loginSelection": "Login Selection", - "selectCountryCode": "Please select Country Code", - "selectProviderRole": "Please select Provider Role", - "addPhoneNo": "Please add Phone No", - "onlyCustomerApp": "Sorry, Only Customer's can log in this app", - "imageUploaded": "Image is uploaded", - "fileLarger": "File is larger then 1KB", - "account": "Account", - "edit": "EDIT", - "imageDeleted": "Image is Deleted", - "dashboard": "Dashboard/Main Page", - "termsOfService": "By creating an account you agree to our", - "userInformation": "User Information", - "faceRecognition": "Face Recognition", - "fingerPrint": "Finger Print", - "whatsapp": "With Whatsapp", - "SMS": "With SMS", - "selectRole": "Select Role", - "userRoleOrTitle": "User role or title", - "codeSentToEmail": "Code is sent to email", - "number": "Number", - "english": "English", - "title": "Hello", - "msg": "Hello {} in the {} world ", - "msg_named": "{} are written in the {lang} language", - "clickMe": "Click me", - "profile": { - "reset_password": {"label": "Reset Password", "username": "Username", "password": "password"} - }, - "clicked": { - "zero": "You clicked {} times!", - "one": "You clicked {} time!", - "two": "You clicked {} times!", - "few": "You clicked {} times!", - "many": "You clicked {} times!", - "other": "You clicked {} times!" - }, - "amount": {"zero": "Your amount : {} ", "one": "Your amount : {} ", "two": "Your amount : {} ", "few": "Your amount : {} ", "many": "Your amount : {} ", "other": "Your amount : {} "}, - "gender": { - "male": "Hi man ;) ", - "female": "Hello girl :)", - "with_arg": {"male": "Hi man ;) {}", "female": "Hello girl :) {}"} - }, - "reset_locale": "Reset Language", - "welcomeDes": "You one stop place all your car needs", - "log_in": "Log In", - "send": "Send", - "phoneNumber": "Phone Number", - "forgetPasswordQ": "Forget Password?", - "recover": "Recover", - "retrivePassword": "Retrive password by one of following method", - "retriveOnPhone": "We will send the opt to your registered mobile number", - "retriveOnEmail": "We will send the opt to your registered email address", - "enterPhoneForVerfication": "Please enter your phone number We will send you the verification code", - "welcomeBack": "Welcome Back!!!", - "selectYourCountry": "Select Your Country", - "chooseCountry": "Choose Country", - "terms": "Terms of Service and Privacy Policy", - "profileMsg": "Enter the details below and complete the profile info", - "save": "Save", - "insert_otp_code": "Enter the code", - "type_code": "Please type the code we sent to", - "resend_code": "Resend Code", - "check_code": "Check Code", - "time_will_expire": "Resend code in", - "sec": "sec", - "providers": "Providers", - "appointments": "Appointments", - "home": "Home", - "ads": "Ads", - "settings": "Settings", - "view_all": "view all", - "my_active_Ads": "My Active Ads", - "recommended_ads": "Recommended Ads", - "upcoming_appointment": "Upcoming Appointment", - "my_service_providers": "My Recent Service Providers", - "appointment_details": "Appointment Details", - "no_city_available": "No City Available for this country", - "branch_created": "Branch is successfully created", - "branch_updated": "Branch is successfully Updated", - "branch_deleted": "Branch is successfully Deleted", - "dashboard_main": "Dashboard/Main Page", - "logo_brand": "Logo/Brand", - "remove": "Remove", - "no_branch": "No Branch Added Yet", - "login_once": "Please login once", - "defineLicenese": "Upload Licenses and Certificates", - "description": "Description", - "attachFile": "Attach File", - "branchLocation": "Branch info and Location", - "tapToEdit": "Tap to edit", - "myServiceBranches": "My Service Branches", - "enter_licence_detail": "Please enter the detail for commercial records and attach the license images", - "country": "Country", - "city": "City", - "editServices": "Edit Services", - "maintenance": "Maintenance", - "accessories_modifications": "Accessories and Modifications", - "my_recent_providers": "My Recent Service Providers", - "my_active_ads": "My Active Ads", - "recommended_Ads": "Recommended Ads", - "select_services": "Select services you want", - "location": "Location", - "address": "Address", - "branchName": "Branch Name", - "branchDescription": "Branch Description", - "branchInfo": "Branch Info", - "defineServices": "Define Services", - "defineBranches": "Define Branches", - "defineProviders": "Define Providers", - "closeAccount": "Close Account", - "selectServiceCategory": "Select Service Category", - "selectService": "Select Service", - "selectBranch": "Select Branch", - "createBranch": "Create Branch", - "updateBranch": "Update Branch", - "branches": "Branches", - "requests": "Requests", - "noBranchFound": "No Branch Found", - "pickAddress": "Pick Address", - "pickLocation": "Pick Location", - "chooseCity": "Select City", - "selectAttachment": "Select Attachment", - "somethingWrong": "Something went wrong", - "documentsUploaded": "Documents uploaded successfully", - "update": "Update", - "profileCompleted": "Profile is Completed", - "selectLocationMap": "Select Location Map", - "licensesAndCertifications": "licenses & certifications", - "completeProfile1": "Complete Profile 1/3", - "completeProfile2": "Complete Profile 2/3", - "completeProfile3": "Complete Profile 3/3", - "provider": "Provider", - "noRequeststoShow": "No Requests to Show", - "myBranches": "My Branches", - "mergeAppointments": "Merge Appointments", - "addService": "Add Service", - "selectServicestoAdd": "Select services you want to add", - "noServiceFound": "No Service Found", - "selectItems": "Select Items", - "noItemSelectedYet": "No Item Selected Yet", - "totalAdditionalAmount": "Total Additional Amount", - "sar": "SAR", - "cancel": "Cancel", - "add": "Add", - "itemsAddedSuccessfully": "Items are added Successfully", - "pleaseSelectItems": "Please select items", - "totalAmount": "Total Amount", - "searchItems": "Search Items", - "addSelectedItems": "Add Selected Items", - "collectMoneyBefore": "Do you want to collect the money before providing services?", - "yes": "Yes", - "no": "No", - "reason": "Reason", - "typeHere": "Type Here...", - "pleaseSelectReason": "Please Select Reason", - "noAppointmentFound": "No Appointment Found", - "slotsOverview": "Slots Overview", - "empty": "Empty", - "occupied": "Occupied", - "totalSlots": "Total Slots", - "selectAppointments": "Select Appointments", - "appointmentMergeSuccessfully": "Appointment Merge is Successfully done", - "updateAppointment": "Update Appointment", - "addNewService": "Add New Service", - "waitingPaymentfromtheCustomer": "Waiting for the payment from the customer", - "appointmentisCompleted": "Appointment is completed", - "workStart": "Work Start", - "payNow": "Pay Now", - "arrived": "Arrived", - "payLater": "Pay Later", - "complete": "Complete", - "makeAnOffer": "Make an offer", - "enterAmount": "Enter amount", - "submit": "Submit", - "viewChat": "View Chat", - "requestDetail": "Request Detail", - "sendOffer": "Send Offer", - "offer": "Offer", - "sendPriceOffer": "Send Price Offer", - "comment": "Comment", - "sendOTP": "Send OTP", - "noUserAddedYet": "No User Added Yet", - "assignDealerUser": "Assign Dealer User", - "createNewUser": "Create New User", - "dealerUser": "Dealer User", - "setorEditBranchSchedule": "Set or Edit Branch Schedule", - "addServices": "Add Services", - "noServiceAddedYet": "No Service Added Yet", - "selectDays": "Select Days", - "addSelectedDays": "Add Selected Days", - "select_Services": "Select Services", - "searchService": "Search Service", - "addSelectedServices": "Add Selected Services", - "nameofSchedule": "Name of Schedule", - "startingDate": "Starting Date", - "endDate": "End Date", - "offDays": "Off Days", - "shiftStartTime": "Shift Start Time", - "shiftEndTime": "Shift End Time", - "slotsTime": "Slots Time", - "appointmentPerSlot": "Appointment Per Slot", - "create": "Create", - "pleaseEnterValidScheduleName": "Please enter valid schedule Name", - "pleaseSelectServices": "Please select Services", - "pleaseSelectStartDate": "Please select start date", - "pleaseSelectEndDate": "Please select end date", - "pleaseSelectOffDays": "Please Select off Days", - "pleaseSelectStartTime": "Please select start time", - "pleaseSelectEndTime": "Please select end time", - "pleaseSelectSlotTime": "Please select slot time", - "pleaseSelectAppointmentPerSlot": "Please select appointment per slot", - "exploreAds": "Explore Ads", - "myAds": "My Ads", - "noAppointmentstoShow": "No Appointments to show", - "myRecommendedAds": "My Recommended Ads", - "model": "Model", - "chooseImageSource": "Choose image source", - "camera": "Camera", - "gallery": "Gallery", - "imageIsDeleted": "Image is Deleted", - "myRequests": "My Requests", - "branchDetail": "Branch Detail", - "time": "Time", - "openMapLocation": "Open Map Location", - "providerProfile": "Provider Profile", - "servicesOffer": "Services Offer", - "noServicesAvailable": "No Services Available", - "bookAppointment": "Book Appointment", - "allowingHomeService": "Allowing home service", - "homeServiceRange": "Home service range", - "chargesPerKM": "Charges per KM", - "providerDetails": "Provider Details", - "someDescriptionExperienceandtheirReputation": "Some description about the provider and their years of experience and their reputation", - "availableforAppointment": "Available for appointment", - "allowingWorkshopService": "Allowing Workshop service", - "serviceAmount": "Service Amount", - "youNeedStoragePermissionFiles.": "You need to give storage permission to select files.", - "settingDeniedPermanently": "This permission was denied permanently, Please go to settings and allow. ", - "openAppSetting": "Open App Setting", - "adDuration": "Ad Duration", - "startDate": "Start Date", - "contactDetails": "Contact Details", - "showyournumbertoBuyers": "Do you want to show your number to the buyers?", - "isNumberRegisteredWhatsApp": "Is this number registered on WhatsApp?", - "selectSpecialServices": "Select Special Services", - "vehicleDetails": "Vehicle Details", - "vehicleModel": "Vehicle Model", - "vehicleColor": "Vehicle Color", - "vehicleCategory": "Vehicle Category", - "vehicleTransmission": "Vehicle Transmission", - "vehicleCountry": "Vehicle Country", - "vehicleAmount": "Vehicle Amount", - "vehicleTitle": "Vehicle Title", - "financeAvailable": "Finance Available", - "vehiclePictures": "Vehicle Pictures", - "vehiclePart": "Vehicle Part", - "damagePartPictures": "Damage Part Pictures", - "vehicleDamagePart": "Vehicle Damage Part", - "duration": "Duration:", - "specialServices": "Special Services", - "specialService": "Special Service", - "adContactDetails": "Ad Contact Details", - "onWhatsAp": "On WhatsAp", - "reserveAdPriceInfo": "Reserve Ad Price Info", - "addDamagePart": "Add Damage Part", - "vehicleType": "Vehicle Type", - "vehicleYear": "Vehicle Year", - "vehicleCondition": "Vehicle Condition", - "vehicleMileage": "Vehicle Mileage", - "sellerType": "Seller Type", - "vehicleCity": "Vehicle City", - "vehicleVIN": "Vehicle VIN", - "warrantyAvailable": "Warranty Available", - "years": "Years", - "vehicleDetail": "Vehicle Detail", - "vehicleBrand": "Vehicle Brand", - "vehicleModelYear": "Vehicle Model Year", - "vehicleSellerType": "Vehicle Seller Type", - "demandAmount": "Demand Amount", - "warrantyAvailableYears": "Warranty Available (No. of Years)", - "vehicleDescription": "Vehicle Description", - "attachImage": "Attach Image", - "useFingerPrintFaceID": "Please use your fingerprint or face ID", - "setupTouchID": "Please set up your Touch ID", - "reenableTouchID": "Please reenable your Touch ID", - "scanFaceIDAuthenticate": "Scan your fingerprint or face ID to authenticate", - "adDeletedSuccessfully": "Ad has been deleted successfully!", - "yourReservationCancelled": "Your reservation has been cancelled.", - "adDeactivatedSuccessfully": "Ad has been deactivated successfully!", - "vehicle": { - "selectVehicleType": "Please select vehicle type", - "selectVehicleModel": "Please select vehicle model", - "selectVehicleModelYear": "Please select vehicle model year", - "selectVehicleColor": "Please select vehicle color", - "vehicleCondition": "Please select vehicle condition", - "vehicleCategory": "Please select vehicle category", - "vehicleMileage": "Please select vehicle Mileage", - "vehicleTransmission": "Please select vehicle transmission", - "vehicleSellerType": "Please select vehicle seller type", - "selectAny": "Please select any", - "vehicleCity": "Please select vehicle city", - "vehiclePart": "Please select vehicle part", - "selectValidVehicleType": "Please select valid Vehicle Type" - }, - "selectAppointmentTimeService": "You must select appointment time the service.", - "error": "Error", - "appointmentBookedSuccessfully": "Your appointment has been booked successfully", - "appointmentStatusUpdated": "Appointment Status Updated", - "paymentStatusUpdated": "Payment Status Updated", - "selectOneSubService": "Please select at least one sub service", - "chargesBreakdown": "Charges Breakdown", - "services": "Services", - "homeLocation": "Home Location", - "selectAppointmentTime": "You must select appointment time for each schedule's appointment", - "noAppointmentAvailable": "There are no available appointments for selected Items", - "changedMind": "I have changed my mind", - "veryHighPrice": "Very High Price", - "alreadySold": "Already Sold", - "otherVar": "Other", - "paymentSuccessful": "Payment Successful", - "paymentFailed": "Payment Failed!", - "requestSuccessfullyCreated": "Request Successfully Created", - "selectValidRequestType": "Please select valid Request Type", - "selectValidBrand": "Please select valid Brand", - "selectValidModel": "Please select valid Model", - "selectValidYear": "Please select valid Year", - "selectValidCountry": "Please select valid Country", - "selectValidCity": "Please select valid City", - "addValidPrice": "Please add valid Price", - "addValidDescription": "Please add valid Description", - "passwordTooShort": "Your password is too short", - "passwordAcceptableStrong": "Your password is acceptable but not strong", - "passwordIsStrong": "Your password is strong", - "passwordVeryStrong": "Your password is very strong", - "onlyProviderApp": "Sorry, Only Customer's can log in this app", - "selectDuration": "Select Duration", - "daysVar": "Days", - "adCharges": "Ad Charges", - "select": "Select", - "deleteAdConfirmation": "Do you want to delete the ad?", - "deleteAdConfirmationMessage": "Your ad will be permanently deleted and you cannot undo this action", - "mileage": "mileage", - "transmission": "Transmission", - "demand": "Demand", - "adDurationExpired": "Your Ad Duration time is over", - "bankDetails": "Bank Details", - "bankName": "Bank Name", - "iban": "IBAN", - "rejectionComments": "Rejection Comments", - "editAd": "Edit Ad", - "reserveAd": "Reserve Ad", - "reservationAmount": "Reservation Amount", - "belowAmountPayLater": "Below Amount that you will pay later", - "carPrice": "Car Price", - "vatExcluded": "VAT Excluded", - "carInsuranceService": "Car insurance Service", - "toBeDecided": "To be Decided", - "registrationCarPlates": "Registration & Car Plates", - "homeDeliveryService": "Home Delivery Service", - "specialServicechargesInsuranceDeliveryLocation": "Special service charges will be added based on desired insurance and delivery Location", - "estimated": "Estimated", - "servicesReservingAd": "Some services are mandatory while reserving Ad", - "completeReservation": "Complete Reservation", - "contact": "Contact", - "setDateandTime": "Set Date and Time", - "selectOffice": "Select Office", - "availableSlots": "Available Slots", - "bookAndPay": "Book and Pay", - "reservationAmounts": "Reservation Amounts", - "tax": "Tax", - "adsFilter": "Ads Filter", - "searchByCity": "Search By City", - "selectCity": "Select City", - "searchByBrandName": "Search By Brand Name", - "selectVehicleBrand": "Select Vehicle Brand", - "searchByVehicleYear": "Search By Vehicle Year", - "selectYear": "Select Year", - "searchByAdOwner": "Search By Ad Owner", - "selectOwner": "Select Owner", - "search": "Search", - "clearFilters": "Clear Filters", - "book": "Book", - "markAsSold": "Mark As Sold", - "deactivateAd": "Deactivate Ad", - "doWantDeactivateAd": "Do you want to the Deactivate this Ad?", - "stoptheBuyers": "We will stop showing this ad to the buyers", - "cancelReservation": "Cancel Reservation", - "reasonForCancellation": "Reason for Cancellation", - "doWantCancelReservation": "Do you want to cancel the reservation", - "yourAdVisibletoBuy.": "Your ad reservation will be cancelled and this ad will be again visible to everyone to buy", - "completeDeal": "Complete Deal", - "uploadBankReceipt": "Upload Bank Receipt", - "notesForAdmin": "Notes For Admin", - "extendAd": "Extend Ad", - "updateAdDetails": "Do you want to update the Ad Details", - "durationExtendingAd": "You can change the ad duration and details before extending the ad", - "waitingAdminsResponse": "Waiting for Admins Response", - "cancelledByOwner": "Cancelled by Owner", - "cancelledByAdmin": "Cancelled by Admin", - "reservationTimeOver": "Reservation Time Over", - "paymentVerified": "Payment Verified", - "rejectedFormAdmin": "Rejected form Admin", - "waitingAdminPost": "Waiting for admin to post", - "waitingAdminsApproval": "Waiting for Admins Approval", - "sold": "Sold", - "noAdsShow": "No Ads to show", - "damagePartList": "Damage Part List", - "searchPart": "Search Part", - "addSpecialService": "Add Special Service", - "vehicleVar": "Vehicle", - "detailsVar": "Details", - "damageVar": "Damage", - "partsVar": "Parts", - "additional": "Additional", - "review": "Review", - "adVar": "Ad", - "updateAd": "Update Ad", - "createAd": "Create Ad", - "next": "Next", - "submitAd": "Submit Ad", - "selectAdType": "Select Ad Type", - "validUntilSubscriptionExpiration": "Valid Until Subscription Expiration", - "adsRemaining ": "Ads Remaining", - "youLeftAdsGivenSubscription": "You have left with 05 out of 50 ads given in the subscription.", - "updateSubscription": "Update Subscription", - "workInProgress": "Work In Progress", - "visitCompleted": "Visit Completed", - "youWantCancelAppointment": "Do you want to cancel this appointment?", - "appointmentCancelledCannotUndoAction": "Your appointment will be cancelled and you cannot undo this action.", - "appointment": "Appointment", - "rescheduleAppointment": "Reschedule Appointment", - "payforAppointment": "Pay for Appointment", - "appointmentsFilter": "Appointments Filter", - "searchByProvider": "Search By Provider", - "selectProvider": "Select Provider", - "searchByBranch": "Search By Branch", - "searchByCategory": "Search By Category", - "selectCategory": "Select Category", - "searchByService": "Search By Service", - "selectServices": "Select Services", - "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", - "subscriptions": "Subscriptions", - "defineLicenses": "Define Licenses", - "logOut": "Log Out", - "customer": "Customer", - "accept": "Accept", - "amountVAR": "Amount", - "requestAlreadyInProgress": "This request is already in progress.", - "acceptOfferConfirmation": "Do you want to accept this offer?", - "acceptOfferConfirmationMessage": "This offer will be accepted and you will pay the requested amount to the buyer in given time or else this offer will be cancelled." - }; - static const Map> mapLocales = {"ar_SA": ar_SA, "en_US": en_US}; + static const Map ar_SA = { + "firstTimeLogIn": "تسجيل الدخول لأول مره", + "signUp": "التسجيل", + "changeMobile": "تغيير رقم الجوال", + "notifications": "الاشعارات", + "general": "عام", + "defineLicences": "تحديد الرخص", + "dealershipSettings": "اعدادات البيع", + "changePassword": "تغيير كلمة المرور", + "retrievePassword": "استرجاع كلمة المرور", + "changeEmail": "تغيير الايميل", + "verify": "تحقق", + "verified": "تم التحقق", + "signOut": "تسجيل خروج", + "enterEmail": "ادخل الايميل", + "enterNewEmail": "ادخل ايميل جديد", + "enterCurrentPassword": "كلمة المرور الحاليه", + "enterNewPassword": "كلمة المرور الجديده", + "enterOldPassword": "كلمة المرور القديمه", + "confirm": "تأكيد", + "enterNewPhoneNumber": "رقم جوال جديد", + "completeProfile": "الملف الشخصي", + "continu": "استمرار", + "confirmPassword": "تأكيد كلمة المرور", + "createPassword": "انشاء كلمة مرور جديده", + "email": "ايميل", + "firstName": "الأسم الأول *", + "surname": "اسم العائله *", + "confirmPass": "تأكيد كلمة المرور *", + "createPass": "انشاء كلمة مرور جديده *", + "newPassword": " كلمة مرور جديده", + "forgetPassword": "نسيت كلمة المرور", + "forgetPasswordRecover": "نسيت كلمة المرور؟ استعادة", + "editAccount": "تعديل الحساب", + "change": "تغيير", + "verifyAccount": "التحقق من الحساب", + "login": "تسجيل دخول", + "welcomeMessage": "مرحبا", + "forgetPass": "نسيت كلمة المرور ؟", + "enterPhoneNumber": "رقم جوال ", + "phoneNumberVerified": "تم التحقق من الجوال", + "verifyNewPassword": "التحقق من كلمة المرور", + "EnterPass": "ادخل كلمة المرور", + "alreadySigned": " تم تسجيل الدخول", + "emailChangedSuccessfully": "تم تغيير الايميل بنجاح", + "passwordIsUpdated": "تم تحجيث كلمة المرور", + "passwordShouldContains": "كلمة المرور يجب ان تحتوي على رمز رقم حرف كبير حرف صغير", + " successfullyRegistered": "تم التسجيل بنجاح", + "pleaseEnterSamePassword": "ادخل كلمة مرور مطابقه", + "firstNameMandatory": "ادخل الأسم الأول ", + "surnameNameMandatory": "ادخل اسم العائله", + "passwordNameMandatory": "ادخل كلمة المرور", + "enterValidEmail": "ادخل ايميل صحيح", + "pleaseAcceptTerms": "يجب الموافقه على الشروط", + "emailVerified": "تم التحقق من الايميل بنجاح", + "selectMethod": "اختر", + "emailAddress": "ايميل", + "loginSelection": "اختر", + "selectCountryCode": "اختر رمز الدوله", + "selectProviderRole": "اختر نوع الخدمه", + "addPhoneNo": "اضف الهاتف", + "onlyCustomerApp": "نأسف هذا التطبيق فقط للعملاء", + "imageUploaded": "تم تحميل الصوره", + "fileLarger": "1KB حجم الملف اكبر من", + "account": "الحساب", + "edit": "تعديل", + "imageDeleted": "تم حذف الصوره", + "dashboard": "الصفحه الرئيسيه", + "termsOfService": "من خلال إنشاء حساب فإنك توافق على", + "userInformation": "معلومات المتسخدم", + "faceRecognition": "تحقق مع بصمة الوجه", + "fingerPrint": "تحقق مع بصمة الاصبع", + "whatsapp": "تحقق مع Whatsapp", + "SMS": "رسائل قصيره", + "selectRole": "حدد الدور", + "userRoleOrTitle": "عنوان المستخدم", + "codeSentToEmail": "تم ارسال الرمز للايميل", + "number": "موبايل", + "english": "عربي", + "title": "مرحبًا", + "msg": "Hello {} in the {} world ", + "msg_named": "{} are written in the {lang} language", + "clickMe": "انقر فوق لي", + "profile": { + "reset_password": { + "label": "إعادة تعيين كلمة المرور", + "username": "اسم المستخدم", + "password": "كلمة المرور" + } + }, + "clicked": { + "zero": "You clicked {} times!", + "one": "You clicked {} time!", + "two": "You clicked {} times!", + "few": "You clicked {} times!", + "many": "You clicked {} times!", + "other": "You clicked {} times!" + }, + "amount": { + "zero": "Your amount : {} ", + "one": "Your amount : {} ", + "two": "Your amount : {} ", + "few": "Your amount : {} ", + "many": "Your amount : {} ", + "other": "Your amount : {} " + }, + "gender": { + "male": "Hi man ;) ", + "female": "Hello girl :)", + "with_arg": { + "male": "Hi man ;) {}", + "female": "Hello girl :) {}" + } + }, + "reset_locale": "إعادة ضبط اللغة", + "welcomeDes": "أنت مكان واحد لكل ما تحتاجه سيارتك", + "log_in": "تسجيل الدخول", + "send": "إرسال", + "phoneNumber": "رقم الهاتف", + "forgetPasswordQ": "نسيت كلمة المرور؟", + "recover": "استعادة", + "retrivePassword": "استرجع كلمة المرور بإحدى الطرق التالية", + "retriveOnPhone": "سوف نرسل الاختيار إلى رقم هاتفك المحمول المسجل", + "retriveOnEmail": "سوف نرسل الاختيار إلى عنوان بريدك الإلكتروني المسجل", + "enterPhoneForVerfication": "الرجاء إدخال رقم هاتفك وسنرسل لك رمز التحقق", + "welcomeBack": "مرحبًا بعودتك!!!", + "selectYourCountry": "اختر بلدك", + "chooseCountry": "اختر الدوله", + "terms": "بنود الخدمة وخصوصية السياسة", + "profileMsg": "أدخل التفاصيل أدناه وأكمل معلومات الملف الشخصي", + "save": "حفظ", + "insert_otp_code": "ادخل الرمز", + "type_code": "الرجاء كتابة الرمز الذي أرسلناه إلى", + "resend_code": "أعد إرسال الرمز", + "check_code": "التحقق من الشفرة", + "time_will_expire": "إعادة إرسال الرمز بتنسيق", + "sec": "ثانية", + "providers": "الموفرون", + "appointments": "تعيينات", + "home": "بيت", + "ads": "إعلانات", + "settings": "إعدادات", + "view_all": "مشاهدة الكل", + "my_active_Ads": "إعلاناتي النشطة", + "recommended_ads": "الإعلانات الموصى بها", + "upcoming_appointment": "الموعد القادم", + "my_service_providers": "مزودي الخدمة الجدد", + "appointment_details": "تفاصيل الموعد", + "no_city_available": "لا توجد مدينة متاحة لهذا البلد", + "branch_created": "تم إنشاء الفرع بنجاح", + "branch_updated": "تم تحديث الفرع بنجاح", + "branch_deleted": "تم حذف الفرع بنجاح", + "dashboard_main": "لوحة القيادة / الصفحة الرئيسية", + "logo_brand": "الشعار / العلامة التجارية", + "remove": "إزالة", + "no_branch": "لم يتم إضافة فرع حتى الآن", + "login_once": "الرجاء تسجيل الدخول مرة واحدة", + "defineLicenese": "تحميل التراخيص والشهادات", + "description": "وصف", + "attachFile": "أرفق ملف", + "branchLocation": "معلومات الفرع والموقع", + "tapToEdit": "انقر للتعديل", + "myServiceBranches": "فروع خدمتي", + "enter_licence_detail": "الرجاء إدخال تفاصيل السجلات التجارية وإرفاق صور الترخيص", + "country": "بلد", + "city": "مدينة", + "editServices": "تحرير الخدمات", + "maintenance": "صيانة", + "accessories_modifications": "الملحقات والتعديلات", + "my_recent_providers": "مزودي الخدمة الجدد", + "my_active_ads": "إعلاناتي النشطة", + "recommended_Ads": "الإعلانات الموصى بها", + "location": "موقع", + "address": "عنوان", + "branchName": "اسم الفرع", + "branchDescription": "وصف الفرع", + "branchInfo": "معلومات الفرع", + "defineServices": "تحديد الخدمات", + "defineBranches": "تحديد الفروع", + "defineProviders": "تحديد الموفرين", + "closeAccount": "حساب مغلق", + "selectServiceCategory": "حدد فئة الخدمة", + "selectService": "حدد الخدمة", + "selectBranch": "حدد الفرع", + "createBranch": "إنشاء فرع", + "updateBranch": "تحديث فرع", + "branches": "الفروع", + "requests": "الطلبات", + "noBranchFound": "لم يتم العثور على فرع", + "onlyProviderApp": "نأسف هذا التطبيق فقط لمقدمي الخدمات", + "pickAddress": "اختر العنوان", + "pickLocation": "اختر الموقع", + "chooseCity": "اختر المدينه", + "selectAttachment": "اختيار مرفق", + "somethingWrong": "هناك خطأ ما", + "documentsUploaded": "تم ارفاق الملف بنجاح", + "update": "تحديث", + "profileCompleted": "الملف الشخصي مكتمل", + "selectLocationMap": "اختر الموقع", + "licensesAndCertifications": "الرخص و الشهادات", + "completeProfile1": "اكمل الملف الشخصي 1/3", + "completeProfile2": "اكمل الملف الشخصي 2/3", + "completeProfile3": "اكمل الملف الشخصي 3/3", + "provider": "مزود", + "noRequeststoShow": "لا توجد طلبات للعرض", + "myBranches": "فروعي", + "mergeAppointments": "دمج المواعيد", + "addService": "أضف الخدمة", + "selectServicestoAdd": "حدد الخدمات التي تريد إضافتها", + "noServiceFound": "لم يتم العثور على الخدمة", + "selectItems": "اختيار العناصر", + "noItemSelectedYet": "لم يتم تحديد أي عنصر بعد", + "totalAdditionalAmount": "إجمالي المبلغ الإضافي", + "sar": "ريال سعودي", + "cancel": "يلغي", + "add": "يضيف", + "itemsAddedSuccessfully": "تمت إضافة العناصر بنجاح", + "pleaseSelectItems": "يرجى اختيار العناصر", + "totalAmount": "المبلغ الإجمالي", + "searchItems": "البحث عن العناصر", + "addSelectedItems": "إضافة العناصر المحددة", + "collectMoneyBefore": "هل ترغب في جمع المال قبل تقديم الخدمات؟", + "yes": "نعم", + "no": "لا", + "reason": "السبب", + "typeHere": "اكتب هنا...", + "pleaseSelectReason": "يرجى تحديد السبب", + "noAppointmentFound": "لم يتم العثور على مواعيد", + "slotsOverview": "نظرة عامة على الفتحات", + "empty": "فارغ", + "occupied": "محجوز", + "totalSlots": "إجمالي الفتحات", + "selectAppointments": "اختيار المواعيد", + "appointmentMergeSuccessfully": "دمج المواعيد تم بنجاح", + "updateAppointment": "تحديث الموعد", + "addNewService": "إضافة خدمة جديدة", + "waitingPaymentfromtheCustomer": "في انتظار الدفع من العميل", + "appointmentisCompleted": "تم اكتمال الموعد", + "workStart": "بدء العمل", + "payNow": "ادفع الآن", + "arrived": "وصل", + "payLater": "ادفع لاحقًا", + "complete": "اكتمل", + "makeAnOffer": "قدم عرضًا", + "enterAmount": "أدخل المبلغ", + "submit": "إرسال", + "viewChat": "عرض الدردشة", + "requestDetail": "تفاصيل الطلب", + "sendOffer": "إرسال عرض", + "offer": "عرض", + "sendPriceOffer": "إرسال عرض السعر", + "comment": "تعليق", + "sendOTP": "إرسال رمز OTP", + "noUserAddedYet": "لم يتم إضافة مستخدم بعد", + "assignDealerUser": "تعيين مستخدم تاجر", + "createNewUser": "إنشاء مستخدم جديد", + "dealerUser": "مستخدم تاجر", + "setorEditBranchSchedule": "تعيين أو تحرير جدول الفروع", + "addServices": "إضافة خدمات", + "noServiceAddedYet": "لم تتم إضافة خدمات بعد", + "selectDays": "اختيار الأيام", + "addSelectedDays": "إضافة الأيام المحددة", + "select_Services": "اختيار الخدمات", + "searchService": "البحث عن الخدمة", + "addSelectedServices": "إضافة الخدمات المحددة", + "nameofSchedule": "اسم الجدول الزمني", + "startingDate": "تاريخ البدء", + "endDate": "تاريخ الانتهاء", + "offDays": "أيام الراحة", + "shiftStartTime": "وقت بدء الوردية", + "shiftEndTime": "وقت انتهاء الوردية", + "slotsTime": "وقت الفتحات", + "appointmentPerSlot": "موعد لكل فتحة", + "create": "إنشاء", + "pleaseEnterValidScheduleName": "يرجى إدخال اسم جدول صالح", + "pleaseSelectServices": "يرجى اختيار الخدمات", + "pleaseSelectStartDate": "يرجى تحديد تاريخ البدء", + "pleaseSelectEndDate": "يرجى تحديد تاريخ الانتهاء", + "pleaseSelectOffDays": "يرجى تحديد أيام الراحة", + "pleaseSelectStartTime": "يرجى تحديد وقت بدء الوردية", + "pleaseSelectEndTime": "يرجى تحديد وقت انتهاء الوردية", + "pleaseSelectSlotTime": "يرجى تحديد وقت الفتحة", + "pleaseSelectAppointmentPerSlot": "يرجى تحديد موعد لكل فتحة", + "exploreAds": "استكشاف الإعلانات", + "myAds": "إعلاناتي", + "noAppointmentstoShow": "لا توجد مواعيد لعرضها", + "myRecommendedAds": "الإعلانات الموصى بها لي", + "model": "الموديل", + "chooseImageSource": "اختر مصدر الصورة", + "camera": "الكاميرا", + "gallery": "المعرض", + "imageIsDeleted": "تم حذف الصورة", + "myRequests": "طلباتي", + "branchDetail": "تفاصيل الفرع", + "time": "الوقت", + "openMapLocation": "فتح موقع الخريطة", + "providerProfile": "ملف المزود", + "servicesOffer": "الخدمات المقدمة", + "noServicesAvailable": "لا تتوفر خدمات", + "bookAppointment": "حجز موعد", + "allowingHomeService": "السماح بخدمة منزلية", + "homeServiceRange": "نطاق الخدمة المنزلية", + "chargesPerKM": "الرسوم لكل كيلومتر", + "providerDetails": "تفاصيل المزود", + "someDescriptionExperienceandtheirReputation": "بعض الوصف عن المزود وسنوات خبرتهم وسمعتهم", + "availableforAppointment": "متاح للموعد", + "allowingWorkshopService": "السماح بخدمة ورشة العمل", + "serviceAmount": "مبلغ الخدمة", + "youNeedStoragePermissionFiles": "تحتاج إلى منح إذن التخزين لاختيار الملفات.", + "settingDeniedPermanently": "تم رفض هذا الإذن بشكل دائم، يرجى الذهاب إلى الإعدادات والسماح.", + "openAppSetting": "افتح إعدادات التطبيق", + "adDuration": "مدة الإعلان", + "startDate": "تاريخ البدء", + "contactDetails": "تفاصيل الاتصال", + "showyournumbertoBuyers": "هل تريد إظهار رقمك للمشترين؟", + "isNumberRegisteredWhatsApp": "هل هذا الرقم مسجل على واتساب؟", + "selectSpecialServices": "اختر الخدمات الخاصة", + "vehicleDetails": "تفاصيل المركبة", + "vehicleModel": "طراز المركبة", + "vehicleColor": "لون المركبة", + "vehicleCategory": "فئة المركبة", + "vehicleTransmission": "نقل المركبة", + "vehicleCountry": "بلد المركبة", + "vehicleAmount": "مبلغ المركبة", + "vehicleTitle": "عنوان المركبة", + "financeAvailable": "التمويل متاح", + "vehiclePictures": "صور المركبة", + "vehiclePart": "جزء المركبة", + "damagePartPictures": "صور الأجزاء المتضررة", + "vehicleDamagePart": "جزء المركبة المتضرر", + "duration": ":المدة", + "specialServices": "الخدمات الخاصة", + "specialService": "خدمة خاصة", + "adContactDetails": "تفاصيل الاتصال بالإعلان", + "onWhatsAp": "على واتساب", + "reserveAdPriceInfo": "معلومات سعر الإعلان المحجوز", + "addDamagePart": "إضافة جزء متضرر", + "vehicleType": "نوع المركبة", + "vehicleYear": "سنة المركبة", + "vehicleCondition": "حالة المركبة", + "vehicleMileage": "عدد الأميال للمركبة", + "sellerType": "نوع البائع", + "vehicleCity": "مدينة المركبة", + "vehicleVIN": "رقم تعريف المركبة (VIN)", + "warrantyAvailable": "الضمان متاح", + "years": "سنوات", + "vehicleDetail": "تفاصيل المركبة", + "vehicleBrand": "ماركة المركبة", + "vehicleModelYear": "سنة طراز المركبة", + "vehicleSellerType": "نوع بائع المركبة", + "demandAmount": "المبلغ المطلوب", + "warrantyAvailableYears": "الضمان متاح (عدد السنوات)", + "vehicleDescription": "وصف المركبة", + "attachImage": "إرفاق صورة", + "useFingerPrintFaceID": "يرجى استخدام بصمة الإصبع أو معرف الوجه", + "setupTouchID": "يرجى إعداد معرف اللمس", + "reenableTouchID": "يرجى إعادة تمكين معرف اللمس", + "scanFaceIDAuthenticate": "امسح بصمة الإصبع أو معرف الوجه للتحقق", + "AdDeletedSuccessfully": "تم حذف الإعلان بنجاح!", + "yourReservationCancelled": "تم إلغاء حجزك.", + "adDeactivatedSuccessfully": "تم إلغاء تفعيل الإعلان بنجاح!", + "vehicle": { + "selectVehicleType": "يرجى اختيار نوع السيارة", + "selectVehicleModel": "يرجى اختيار طراز السيارة", + "selectVehicleModelYear": "يرجى اختيار سنة طراز السيارة", + "selectVehicleColor": "يرجى اختيار لون السيارة", + "vehicleCondition": "يرجى اختيار حالة السيارة", + "vehicleCategory": "يرجى اختيار فئة السيارة", + "vehicleMileage": "يرجى اختيار عدد أميال السيارة", + "vehicleTransmission": "يرجى اختيار نوع ناقل الحركة", + "vehicleSellerType": "يرجى اختيار نوع بائع السيارة", + "selectAny": "يرجى اختيار أي خيار", + "vehicleCity": "يرجى اختيار مدينة السيارة", + "vehiclePart": "يرجى اختيار جزء السيارة", + "selectValidVehicleType": "يرجى اختيار نوع سيارة صالح" + }, + "selectAppointmentTimeService": "يجب عليك اختيار وقت الموعد للخدمة.", + "error": "خطأ", + "appointmentBookedSuccessfully": "تم حجز موعدك بنجاح", + "appointmentStatusUpdated": "تم تحديث حالة الموعد", + "paymentStatusUpdated": "تم تحديث حالة الدفع", + "selectOneSubService": "يرجى اختيار خدمة فرعية واحدة على الأقل", + "chargesBreakdown": "تفاصيل الرسوم", + "services": "الخدمات", + "homeLocation": "الموقع المنزلي", + "selectAppointmentTime": "يجب عليك اختيار وقت الموعد لكل موعد في الجدول", + "noAppointmentAvailable": "لا توجد مواعيد متاحة للعناصر المحددة", + "changedMind": "لقد غيرت رأيي", + "veryHighPrice": "السعر مرتفع جداً", + "alreadySold": "تم البيع بالفعل", + "otherVar": "أخرى", + "paymentSuccessful": "تم الدفع بنجاح", + "paymentFailed": "فشل الدفع!", + "requestSuccessfullyCreated": "تم إنشاء الطلب بنجاح", + "selectValidRequestType": "يرجى اختيار نوع طلب صالح", + "selectValidBrand": "يرجى اختيار علامة تجارية صالحة", + "selectValidModel": "يرجى اختيار طراز صالح", + "selectValidYear": "يرجى اختيار سنة صالحة", + "selectValidCountry": "يرجى اختيار بلد صالح", + "selectValidCity": "يرجى اختيار مدينة صالحة", + "addValidPrice": "يرجى إضافة سعر صالح", + "addValidDescription": "يرجى إضافة وصف صالح", + "passwordTooShort": "كلمة المرور الخاصة بك قصيرة جدًا", + "passwordAcceptableStrong": "كلمة المرور الخاصة بك مقبولة ولكنها ليست قوية", + "passwordIsStrong": "كلمة المرور الخاصة بك قوية", + "passwordVeryStrong": "كلمة المرور الخاصة بك قوية جدًا", + "selectDuration": "اختر المدة", + "daysVar": "الأيام", + "adCharges": "رسوم الإعلان", + "select": "اختر", + "deleteAdConfirmation": "هل تريد حذف الإعلان؟", + "deleteAdConfirmationMessage": "سيتم حذف إعلانك نهائيًا ولا يمكنك التراجع عن هذا الإجراء", + "mileage": "المسافة المقطوعة", + "transmission": "ناقل الحركة", + "demand": "الطلب", + "adDurationExpired": "انتهت مدة عرض الإعلان الخاص بك", + "bankDetails": "تفاصيل البنك", + "bankName": "اسم البنك", + "iban": "الرقم الدولي للحساب المصرفي (IBAN)", + "rejectionComments": "تعليقات الرفض", + "editAd": "تعديل الإعلان", + "reserveAd": "حجز الإعلان", + "reservationAmount": "مبلغ الحجز", + "belowAmountPayLater": "المبلغ الذي ستدفعه لاحقًا", + "carPrice": "سعر السيارة", + "vatExcluded": "القيمة المضافة غير مشمولة", + "carInsuranceService": "خدمة التأمين على السيارة", + "toBeDecided": "لم يتم اتخاذ القرار بعد", + "registrationCarPlates": "تسجيل ولوحات السيارة", + "homeDeliveryService": "خدمة التوصيل إلى المنزل", + "specialServicechargesInsuranceDeliveryLocation": "سيتم إضافة رسوم خدمة خاصة بناءً على التأمين المطلوب وموقع التسليم", + "estimated": "مقدر", + "servicesReservingAd": "بعض الخدمات إلزامية أثناء حجز الإعلان", + "completeReservation": "إتمام الحجز", + "contact": "اتصال", + "setDateandTime": "تحديد التاريخ والوقت", + "selectOffice": "اختيار المكتب", + "availableSlots": "المواعيد المتاحة", + "bookAndPay": "الحجز والدفع", + "reservationAmounts": "مبالغ الحجز", + "tax": "الضريبة", + "adsFilter": "تصفية الإعلانات", + "searchByCity": "البحث حسب المدينة", + "selectCity": "اختر المدينة", + "searchByBrandName": "البحث حسب اسم العلامة التجارية", + "selectVehicleBrand": "اختر علامة تجارية للسيارة", + "searchByVehicleYear": "البحث حسب سنة السيارة", + "selectYear": "اختر السنة", + "searchByAdOwner": "البحث حسب مالك الإعلان", + "selectOwner": "اختر المالك", + "search": "بحث", + "clearFilters": "مسح التصفية", + "book": "حجز", + "markAsSold": "وضع علامة تم البيع", + "deactivateAd": "إلغاء تفعيل الإعلان", + "doWantDeactivateAd": "هل تريد إلغاء تفعيل هذا الإعلان؟", + "stoptheBuyers": "سنتوقف عن عرض هذا الإعلان للمشترين", + "cancelReservation": "إلغاء الحجز", + "reasonForCancellation": "سبب الإلغاء", + "doWantCancelReservation": "هل تريد إلغاء الحجز؟", + "yourAdVisibletoBuy": "سيتم إلغاء حجز إعلانك وسيكون هذا الإعلان مرئيًا للجميع مرة أخرى للشراء", + "completeDeal": "إتمام الصفقة", + "uploadBankReceipt": "تحميل إيصال البنك", + "notesForAdmin": "ملاحظات للإدارة", + "extendAd": "تمديد الإعلان", + "updateAdDetails": "هل تريد تحديث تفاصيل الإعلان", + "durationExtendingAd": "يمكنك تغيير مدة الإعلان والتفاصيل قبل تمديد الإعلان", + "waitingAdminsResponse": "في انتظار رد الإدارة", + "cancelledByOwner": "ألغيت من قبل المالك", + "cancelledByAdmin": "ألغيت من قبل الإدارة", + "reservationTimeOver": "انتهى وقت الحجز", + "paymentVerified": "تم التحقق من الدفع", + "rejectedFormAdmin": "تم الرفض من قبل الإدارة", + "waitingAdminPost": "في انتظار الإدارة للنشر", + "waitingAdminsApproval": "في انتظار موافقة الإدارة", + "sold": "تم البيع", + "noAdsShow": "لا توجد إعلانات لعرضها", + "damagePartList": "قائمة الأجزاء المتضررة", + "searchPart": "البحث عن جزء", + "addSpecialService": "إضافة خدمة خاصة", + "vehicleVar": "السيارة", + "detailsVar": "التفاصيل", + "damageVar": "الضرر", + "partsVar": "الأجزاء", + "additional": "إضافي", + "review": "مراجعة", + "adVar": "الإعلان", + "updateAd": "تحديث الإعلان", + "createAd": "إنشاء إعلان", + "next": "التالي", + "submitAd": "إرسال الإعلان", + "selectAdType": "اختر نوع الإعلان", + "validUntilSubscriptionExpiration": "صالح حتى انتهاء الاشتراك", + "adsRemainingVar": "الإعلانات المتبقية", + "youLeftAdsGivenSubscription": "لقد بقي لديك 05 من 50 إعلانًا في الاشتراك.", + "updateSubscription": "تحديث الاشتراك", + "workInProgress": "العمل جارٍ", + "visitCompleted": "تمت الزيارة", + "youWantCancelAppointment": "هل تريد إلغاء هذا الموعد؟", + "appointmentCancelledCannotUndoAction": "سيتم إلغاء موعدك ولا يمكنك التراجع عن هذا الإجراء", + "appointment": "الموعد", + "rescheduleAppointment": "إعادة جدولة الموعد", + "payforAppointment": "دفع ثمن الموعد", + "appointmentsFilter": "تصفية المواعيد", + "searchByProvider": "البحث حسب المزود", + "selectProvider": "اختر المزود", + "searchByBranch": "البحث حسب الفرع", + "searchByCategory": "البحث حسب الفئة", + "selectCategory": "اختر الفئة", + "searchByService": "البحث حسب الخدمة", + "selectServices": "اختر الخدمات", + "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": "اللغة", + "mySubscription": "اشتراكاتي", + "subscriptions": "الاشتراكات", + "defineLicenses": "تحديد التراخيص", + "logOut": "تسجيل الخروج", + "customer": "العميل", + "amountVAR": "كمية", + "accept": "قبول", + "nowVar": "الآن", + "whendoyouWanttoUpgrade": "متى تريد الترقية", + "yourSubscriptionUpgradeAffectingFrom": "سيتم ترقية اشتراكك الآن. ساري المفعول من", + "upgradeAfterCurrentExpiry": "الترقية بعد انتهاء الاشتراك الحالي", + "yourSubscriptionUpgradeCurrentSubscriptionAffectingFrom": "سيتم ترقية اشتراكك بعد انتهاء اشتراكك الحالي. ساري المفعول من", + "upgradeVar": "ترقية", + "whendoyouWanttoRenew": "متى تريد التجديد", + "renewVar": "تجديد", + "requestAlreadyInProgress": "هذا الطلب قيد التقدم بالفعل.", + "acceptOfferConfirmation": "هل تريد قبول هذا العرض؟", + "acceptOfferConfirmationMessage": "سيتم قبول هذا العرض وستدفع المبلغ المطلوب للمشتري في وقت معين وإلا سيتم إلغاء هذا العرض.", + "noUpcomingAppointments": "لا يوجد موعد قادم متاح", + "addNewAppointment": "إضافة موعد جديد" +}; +static const Map en_US = { + "firstTimeLogIn": "First Time Log In", + "signUp": "Sign Up", + "changeMobile": "Change Mobile", + "notifications": "Notifications", + "general": "General", + "defineLicences": "Define Licences", + "dealershipSettings": "Dealership Settings", + "changePassword": "Change Password", + "retrievePassword": "Retrieve Password", + "changeEmail": "Change Email", + "verify": "Verify", + "verified": "Verified", + "signOut": "Sign Out", + "enterEmail": "Enter Email", + "enterNewEmail": "Enter New Email", + "enterNewPassword": "Enter New Password", + "enterCurrentPassword": "Enter Current Password", + "enterOldPassword": "Enter Old Password", + "confirm": "Confirm", + "completeProfile": "Complete Profile", + "enterNewPhoneNumber": "Enter New Phone Number", + "enterPhoneNumber": "Enter Phone Number", + "continu": "Continue", + "confirmPassword": "Confirm Password", + "createPassword": "Create Password", + "email": "Email", + "firstName": "First Name *", + "surname": "Surname *", + "confirmPass": "Confirm Password *", + "createPass": "Create Password *", + "newPassword": "New Password", + "forgetPassword": "Forget Password", + "forgetPasswordRecover": "Forget Password? Recover", + "editAccount": "Edit Account", + "change": "Change", + "verifyAccount": "Verify Account", + "login": "Log In", + "welcomeMessage": "Welcome Message", + "forgetPass": "Forget Password ?", + "phoneNumberVerified": "Phone Number Verified", + "verifyNewPassword": "Verify New Password", + "EnterPass": "Enter Password ?", + "alreadySigned": " Already Signed Up and Logged In", + "emailChangedSuccessfully": "Email is Changed Successfully", + "passwordIsUpdated": "Password is Updated", + "passwordShouldContains": "Password Should contains Character, Number, Capital and small letters,", + " successfullyRegistered": " Successfully Registered, Please login once,", + "pleaseEnterSamePassword": "Please enter same password", + "firstNameMandatory": "First name is mandatory", + "surnameNameMandatory": "Surname is mandatory", + "passwordNameMandatory": "Password is mandatory", + "enterValidEmail": "Enter Valid Email", + "pleaseAcceptTerms": "Please accept terms", + "emailVerified": "Email is verified successfully", + "selectMethod": "Select Method", + "emailAddress": "Email Address", + "loginSelection": "Login Selection", + "selectCountryCode": "Please select Country Code", + "selectProviderRole": "Please select Provider Role", + "addPhoneNo": "Please add Phone No", + "onlyCustomerApp": "Sorry, Only Customer's can log in this app", + "imageUploaded": "Image is uploaded", + "fileLarger": "File is larger then 1KB", + "account": "Account", + "edit": "EDIT", + "imageDeleted": "Image is Deleted", + "dashboard": "Dashboard/Main Page", + "termsOfService": "By creating an account you agree to our", + "userInformation": "User Information", + "faceRecognition": "Face Recognition", + "fingerPrint": "Finger Print", + "whatsapp": "With Whatsapp", + "SMS": "With SMS", + "selectRole": "Select Role", + "userRoleOrTitle": "User role or title", + "codeSentToEmail": "Code is sent to email", + "number": "Number", + "english": "English", + "title": "Hello", + "msg": "Hello {} in the {} world ", + "msg_named": "{} are written in the {lang} language", + "clickMe": "Click me", + "profile": { + "reset_password": { + "label": "Reset Password", + "username": "Username", + "password": "password" + } + }, + "clicked": { + "zero": "You clicked {} times!", + "one": "You clicked {} time!", + "two": "You clicked {} times!", + "few": "You clicked {} times!", + "many": "You clicked {} times!", + "other": "You clicked {} times!" + }, + "amount": { + "zero": "Your amount : {} ", + "one": "Your amount : {} ", + "two": "Your amount : {} ", + "few": "Your amount : {} ", + "many": "Your amount : {} ", + "other": "Your amount : {} " + }, + "gender": { + "male": "Hi man ;) ", + "female": "Hello girl :)", + "with_arg": { + "male": "Hi man ;) {}", + "female": "Hello girl :) {}" + } + }, + "reset_locale": "Reset Language", + "welcomeDes": "You one stop place all your car needs", + "log_in": "Log In", + "send": "Send", + "phoneNumber": "Phone Number", + "forgetPasswordQ": "Forget Password?", + "recover": "Recover", + "retrivePassword": "Retrive password by one of following method", + "retriveOnPhone": "We will send the opt to your registered mobile number", + "retriveOnEmail": "We will send the opt to your registered email address", + "enterPhoneForVerfication": "Please enter your phone number We will send you the verification code", + "welcomeBack": "Welcome Back!!!", + "selectYourCountry": "Select Your Country", + "chooseCountry": "Choose Country", + "terms": "Terms of Service and Privacy Policy", + "profileMsg": "Enter the details below and complete the profile info", + "save": "Save", + "insert_otp_code": "Enter the code", + "type_code": "Please type the code we sent to", + "resend_code": "Resend Code", + "check_code": "Check Code", + "time_will_expire": "Resend code in", + "sec": "sec", + "providers": "Providers", + "appointments": "Appointments", + "home": "Home", + "ads": "Ads", + "settings": "Settings", + "view_all": "view all", + "my_active_Ads": "My Active Ads", + "recommended_ads": "Recommended Ads", + "upcoming_appointment": "Upcoming Appointment", + "my_service_providers": "My Recent Service Providers", + "appointment_details": "Appointment Details", + "no_city_available": "No City Available for this country", + "branch_created": "Branch is successfully created", + "branch_updated": "Branch is successfully Updated", + "branch_deleted": "Branch is successfully Deleted", + "dashboard_main": "Dashboard/Main Page", + "logo_brand": "Logo/Brand", + "remove": "Remove", + "no_branch": "No Branch Added Yet", + "login_once": "Please login once", + "defineLicenese": "Upload Licenses and Certificates", + "description": "Description", + "attachFile": "Attach File", + "branchLocation": "Branch info and Location", + "tapToEdit": "Tap to edit", + "myServiceBranches": "My Service Branches", + "enter_licence_detail": "Please enter the detail for commercial records and attach the license images", + "country": "Country", + "city": "City", + "editServices": "Edit Services", + "maintenance": "Maintenance", + "accessories_modifications": "Accessories and Modifications", + "my_recent_providers": "My Recent Service Providers", + "my_active_ads": "My Active Ads", + "recommended_Ads": "Recommended Ads", + "select_services": "Select services you want", + "location": "Location", + "address": "Address", + "branchName": "Branch Name", + "branchDescription": "Branch Description", + "branchInfo": "Branch Info", + "defineServices": "Define Services", + "defineBranches": "Define Branches", + "defineProviders": "Define Providers", + "closeAccount": "Close Account", + "selectServiceCategory": "Select Service Category", + "selectService": "Select Service", + "selectBranch": "Select Branch", + "createBranch": "Create Branch", + "updateBranch": "Update Branch", + "branches": "Branches", + "requests": "Requests", + "noBranchFound": "No Branch Found", + "pickAddress": "Pick Address", + "pickLocation": "Pick Location", + "chooseCity": "Select City", + "selectAttachment": "Select Attachment", + "somethingWrong": "Something went wrong", + "documentsUploaded": "Documents uploaded successfully", + "update": "Update", + "profileCompleted": "Profile is Completed", + "selectLocationMap": "Select Location Map", + "licensesAndCertifications": "licenses & certifications", + "completeProfile1": "Complete Profile 1/3", + "completeProfile2": "Complete Profile 2/3", + "completeProfile3": "Complete Profile 3/3", + "provider": "Provider", + "noRequeststoShow": "No Requests to Show", + "myBranches": "My Branches", + "mergeAppointments": "Merge Appointments", + "addService": "Add Service", + "selectServicestoAdd": "Select services you want to add", + "noServiceFound": "No Service Found", + "selectItems": "Select Items", + "noItemSelectedYet": "No Item Selected Yet", + "totalAdditionalAmount": "Total Additional Amount", + "sar": "SAR", + "cancel": "Cancel", + "add": "Add", + "itemsAddedSuccessfully": "Items are added Successfully", + "pleaseSelectItems": "Please select items", + "totalAmount": "Total Amount", + "searchItems": "Search Items", + "addSelectedItems": "Add Selected Items", + "collectMoneyBefore": "Do you want to collect the money before providing services?", + "yes": "Yes", + "no": "No", + "reason": "Reason", + "typeHere": "Type Here...", + "pleaseSelectReason": "Please Select Reason", + "noAppointmentFound": "No Appointment Found", + "slotsOverview": "Slots Overview", + "empty": "Empty", + "occupied": "Occupied", + "totalSlots": "Total Slots", + "selectAppointments": "Select Appointments", + "appointmentMergeSuccessfully": "Appointment Merge is Successfully done", + "updateAppointment": "Update Appointment", + "addNewService": "Add New Service", + "waitingPaymentfromtheCustomer": "Waiting for the payment from the customer", + "appointmentisCompleted": "Appointment is completed", + "workStart": "Work Start", + "payNow": "Pay Now", + "arrived": "Arrived", + "payLater": "Pay Later", + "complete": "Complete", + "makeAnOffer": "Make an offer", + "enterAmount": "Enter amount", + "submit": "Submit", + "viewChat": "View Chat", + "requestDetail": "Request Detail", + "sendOffer": "Send Offer", + "offer": "Offer", + "sendPriceOffer": "Send Price Offer", + "comment": "Comment", + "sendOTP": "Send OTP", + "noUserAddedYet": "No User Added Yet", + "assignDealerUser": "Assign Dealer User", + "createNewUser": "Create New User", + "dealerUser": "Dealer User", + "setorEditBranchSchedule": "Set or Edit Branch Schedule", + "addServices": "Add Services", + "noServiceAddedYet": "No Service Added Yet", + "selectDays": "Select Days", + "addSelectedDays": "Add Selected Days", + "select_Services": "Select Services", + "searchService": "Search Service", + "addSelectedServices": "Add Selected Services", + "nameofSchedule": "Name of Schedule", + "startingDate": "Starting Date", + "endDate": "End Date", + "offDays": "Off Days", + "shiftStartTime": "Shift Start Time", + "shiftEndTime": "Shift End Time", + "slotsTime": "Slots Time", + "appointmentPerSlot": "Appointment Per Slot", + "create": "Create", + "pleaseEnterValidScheduleName": "Please enter valid schedule Name", + "pleaseSelectServices": "Please select Services", + "pleaseSelectStartDate": "Please select start date", + "pleaseSelectEndDate": "Please select end date", + "pleaseSelectOffDays": "Please Select off Days", + "pleaseSelectStartTime": "Please select start time", + "pleaseSelectEndTime": "Please select end time", + "pleaseSelectSlotTime": "Please select slot time", + "pleaseSelectAppointmentPerSlot": "Please select appointment per slot", + "exploreAds": "Explore Ads", + "myAds": "My Ads", + "noAppointmentstoShow": "No Appointments to show", + "myRecommendedAds": "My Recommended Ads", + "model": "Model", + "chooseImageSource": "Choose image source", + "camera": "Camera", + "gallery": "Gallery", + "imageIsDeleted": "Image is Deleted", + "myRequests": "My Requests", + "branchDetail": "Branch Detail", + "time": "Time", + "openMapLocation": "Open Map Location", + "providerProfile": "Provider Profile", + "servicesOffer": "Services Offer", + "noServicesAvailable": "No Services Available", + "bookAppointment": "Book Appointment", + "allowingHomeService": "Allowing home service", + "homeServiceRange": "Home service range", + "chargesPerKM": "Charges per KM", + "providerDetails": "Provider Details", + "someDescriptionExperienceandtheirReputation": "Some description about the provider and their years of experience and their reputation", + "availableforAppointment": "Available for appointment", + "allowingWorkshopService": "Allowing Workshop service", + "serviceAmount": "Service Amount", + "youNeedStoragePermissionFiles.": "You need to give storage permission to select files.", + "settingDeniedPermanently": "This permission was denied permanently, Please go to settings and allow. ", + "openAppSetting": "Open App Setting", + "adDuration": "Ad Duration", + "startDate": "Start Date", + "contactDetails": "Contact Details", + "showyournumbertoBuyers": "Do you want to show your number to the buyers?", + "isNumberRegisteredWhatsApp": "Is this number registered on WhatsApp?", + "selectSpecialServices": "Select Special Services", + "vehicleDetails": "Vehicle Details", + "vehicleModel": "Vehicle Model", + "vehicleColor": "Vehicle Color", + "vehicleCategory": "Vehicle Category", + "vehicleTransmission": "Vehicle Transmission", + "vehicleCountry": "Vehicle Country", + "vehicleAmount": "Vehicle Amount", + "vehicleTitle": "Vehicle Title", + "financeAvailable": "Finance Available", + "vehiclePictures": "Vehicle Pictures", + "vehiclePart": "Vehicle Part", + "damagePartPictures": "Damage Part Pictures", + "vehicleDamagePart": "Vehicle Damage Part", + "duration": "Duration:", + "specialServices": "Special Services", + "specialService": "Special Service", + "adContactDetails": "Ad Contact Details", + "onWhatsAp": "On WhatsAp", + "reserveAdPriceInfo": "Reserve Ad Price Info", + "addDamagePart": "Add Damage Part", + "vehicleType": "Vehicle Type", + "vehicleYear": "Vehicle Year", + "vehicleCondition": "Vehicle Condition", + "vehicleMileage": "Vehicle Mileage", + "sellerType": "Seller Type", + "vehicleCity": "Vehicle City", + "vehicleVIN": "Vehicle VIN", + "warrantyAvailable": "Warranty Available", + "years": "Years", + "vehicleDetail": "Vehicle Detail", + "vehicleBrand": "Vehicle Brand", + "vehicleModelYear": "Vehicle Model Year", + "vehicleSellerType": "Vehicle Seller Type", + "demandAmount": "Demand Amount", + "warrantyAvailableYears": "Warranty Available (No. of Years)", + "vehicleDescription": "Vehicle Description", + "attachImage": "Attach Image", + "useFingerPrintFaceID": "Please use your fingerprint or face ID", + "setupTouchID": "Please set up your Touch ID", + "reenableTouchID": "Please reenable your Touch ID", + "scanFaceIDAuthenticate": "Scan your fingerprint or face ID to authenticate", + "adDeletedSuccessfully": "Ad has been deleted successfully!", + "yourReservationCancelled": "Your reservation has been cancelled.", + "adDeactivatedSuccessfully": "Ad has been deactivated successfully!", + "vehicle": { + "selectVehicleType": "Please select vehicle type", + "selectVehicleModel": "Please select vehicle model", + "selectVehicleModelYear": "Please select vehicle model year", + "selectVehicleColor": "Please select vehicle color", + "vehicleCondition": "Please select vehicle condition", + "vehicleCategory": "Please select vehicle category", + "vehicleMileage": "Please select vehicle Mileage", + "vehicleTransmission": "Please select vehicle transmission", + "vehicleSellerType": "Please select vehicle seller type", + "selectAny": "Please select any", + "vehicleCity": "Please select vehicle city", + "vehiclePart": "Please select vehicle part", + "selectValidVehicleType": "Please select valid Vehicle Type" + }, + "selectAppointmentTimeService": "You must select appointment time the service.", + "error": "Error", + "appointmentBookedSuccessfully": "Your appointment has been booked successfully", + "appointmentStatusUpdated": "Appointment Status Updated", + "paymentStatusUpdated": "Payment Status Updated", + "selectOneSubService": "Please select at least one sub service", + "chargesBreakdown": "Charges Breakdown", + "services": "Services", + "homeLocation": "Home Location", + "selectAppointmentTime": "You must select appointment time for each schedule's appointment", + "noAppointmentAvailable": "There are no available appointments for selected Items", + "changedMind": "I have changed my mind", + "veryHighPrice": "Very High Price", + "alreadySold": "Already Sold", + "otherVar": "Other", + "paymentSuccessful": "Payment Successful", + "paymentFailed": "Payment Failed!", + "requestSuccessfullyCreated": "Request Successfully Created", + "selectValidRequestType": "Please select valid Request Type", + "selectValidBrand": "Please select valid Brand", + "selectValidModel": "Please select valid Model", + "selectValidYear": "Please select valid Year", + "selectValidCountry": "Please select valid Country", + "selectValidCity": "Please select valid City", + "addValidPrice": "Please add valid Price", + "addValidDescription": "Please add valid Description", + "passwordTooShort": "Your password is too short", + "passwordAcceptableStrong": "Your password is acceptable but not strong", + "passwordIsStrong": "Your password is strong", + "passwordVeryStrong": "Your password is very strong", + "onlyProviderApp": "Sorry, Only Providers can log in this app", + "selectDuration": "Select Duration", + "daysVar": "Days", + "adCharges": "Ad Charges", + "select": "Select", + "deleteAdConfirmation": "Do you want to delete the ad?", + "deleteAdConfirmationMessage": "Your ad will be permanently deleted and you cannot undo this action", + "mileage": "mileage", + "transmission": "Transmission", + "demand": "Demand", + "adDurationExpired": "Your Ad Duration time is over", + "bankDetails": "Bank Details", + "bankName": "Bank Name", + "iban": "IBAN", + "rejectionComments": "Rejection Comments", + "editAd": "Edit Ad", + "reserveAd": "Reserve Ad", + "reservationAmount": "Reservation Amount", + "belowAmountPayLater": "Below Amount that you will pay later", + "carPrice": "Car Price", + "vatExcluded": "VAT Excluded", + "carInsuranceService": "Car insurance Service", + "toBeDecided": "To be Decided", + "registrationCarPlates": "Registration & Car Plates", + "homeDeliveryService": "Home Delivery Service", + "specialServicechargesInsuranceDeliveryLocation": "Special service charges will be added based on desired insurance and delivery Location", + "estimated": "Estimated", + "servicesReservingAd": "Some services are mandatory while reserving Ad", + "completeReservation": "Complete Reservation", + "contact": "Contact", + "setDateandTime": "Set Date and Time", + "selectOffice": "Select Office", + "availableSlots": "Available Slots", + "bookAndPay": "Book and Pay", + "reservationAmounts": "Reservation Amounts", + "tax": "Tax", + "adsFilter": "Ads Filter", + "searchByCity": "Search By City", + "selectCity": "Select City", + "searchByBrandName": "Search By Brand Name", + "selectVehicleBrand": "Select Vehicle Brand", + "searchByVehicleYear": "Search By Vehicle Year", + "selectYear": "Select Year", + "searchByAdOwner": "Search By Ad Owner", + "selectOwner": "Select Owner", + "search": "Search", + "clearFilters": "Clear Filters", + "book": "Book", + "markAsSold": "Mark As Sold", + "deactivateAd": "Deactivate Ad", + "doWantDeactivateAd": "Do you want to the Deactivate this Ad?", + "stoptheBuyers": "We will stop showing this ad to the buyers", + "cancelReservation": "Cancel Reservation", + "reasonForCancellation": "Reason for Cancellation", + "doWantCancelReservation": "Do you want to cancel the reservation", + "yourAdVisibletoBuy.": "Your ad reservation will be cancelled and this ad will be again visible to everyone to buy", + "completeDeal": "Complete Deal", + "uploadBankReceipt": "Upload Bank Receipt", + "notesForAdmin": "Notes For Admin", + "extendAd": "Extend Ad", + "updateAdDetails": "Do you want to update the Ad Details", + "durationExtendingAd": "You can change the ad duration and details before extending the ad", + "waitingAdminsResponse": "Waiting for Admins Response", + "cancelledByOwner": "Cancelled by Owner", + "cancelledByAdmin": "Cancelled by Admin", + "reservationTimeOver": "Reservation Time Over", + "paymentVerified": "Payment Verified", + "rejectedFormAdmin": "Rejected form Admin", + "waitingAdminPost": "Waiting for admin to post", + "waitingAdminsApproval": "Waiting for Admins Approval", + "sold": "Sold", + "noAdsShow": "No Ads to show", + "damagePartList": "Damage Part List", + "searchPart": "Search Part", + "addSpecialService": "Add Special Service", + "vehicleVar": "Vehicle", + "detailsVar": "Details", + "damageVar": "Damage", + "partsVar": "Parts", + "additional": "Additional", + "review": "Review", + "adVar": "Ad", + "updateAd": "Update Ad", + "createAd": "Create Ad", + "next": "Next", + "submitAd": "Submit Ad", + "selectAdType": "Select Ad Type", + "validUntilSubscriptionExpiration": "Valid Until Subscription Expiration", + "adsRemainingVar ": "Ads Remaining", + "youLeftAdsGivenSubscription": "You have left with 05 out of 50 ads given in the subscription.", + "updateSubscription": "Update Subscription", + "workInProgress": "Work In Progress", + "visitCompleted": "Visit Completed", + "youWantCancelAppointment": "Do you want to cancel this appointment?", + "appointmentCancelledCannotUndoAction": "Your appointment will be cancelled and you cannot undo this action.", + "appointment": "Appointment", + "rescheduleAppointment": "Reschedule Appointment", + "payforAppointment": "Pay for Appointment", + "appointmentsFilter": "Appointments Filter", + "searchByProvider": "Search By Provider", + "selectProvider": "Select Provider", + "searchByBranch": "Search By Branch", + "searchByCategory": "Search By Category", + "selectCategory": "Select Category", + "searchByService": "Search By Service", + "selectServices": "Select Services", + "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 Subscription", + "subscriptions": "Subscriptions", + "defineLicenses": "Define Licenses", + "logOut": "Log Out", + "customer": "Customer", + "accept": "Accept", + "amountVAR": "Amount", + "requestAlreadyInProgress": "This request is already in progress.", + "acceptOfferConfirmation": "Do you want to accept this offer?", + "acceptOfferConfirmationMessage": "This offer will be accepted and you will pay the requested amount to the buyer in given time or else this offer will be cancelled.", + "nowVar": "Now", + "whendoyouWanttoUpgrade": "When do you want to upgrade", + "yourSubscriptionUpgradeAffectingFrom": "Your subscription will upgrade now. Affecting from", + "upgradeAfterCurrentExpiry": "Upgrade after current expiry", + "yourSubscriptionUpgradeCurrentSubscriptionAffectingFrom": "Your subscription will upgrade after you current subscription will end. Affecting from", + "upgradeVar": "Upgrade", + "whendoyouWanttoRenew": "When do you want to renew", + "renewVar": "Renew", + "noUpcomingAppointments": "No Upcoming Appointment Available.", + "addNewAppointment": "Add New Appointment" +}; +static const Map> mapLocales = {"ar_SA": ar_SA, "en_US": en_US}; } diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index a9cc138..883de6a 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -558,5 +558,7 @@ abstract class LocaleKeys { static const requestAlreadyInProgress = 'requestAlreadyInProgress'; static const acceptOfferConfirmation = 'acceptOfferConfirmation'; static const acceptOfferConfirmationMessage = 'acceptOfferConfirmationMessage'; + static const noUpcomingAppointments = 'noUpcomingAppointments'; + static const addNewAppointment = 'addNewAppointment'; } diff --git a/lib/models/chat_models/buyers_chat_for_ads_model.dart b/lib/models/chat_models/buyers_chat_for_ads_model.dart new file mode 100644 index 0000000..3dd1a42 --- /dev/null +++ b/lib/models/chat_models/buyers_chat_for_ads_model.dart @@ -0,0 +1,21 @@ +class BuyersChatForAdsModel { + int? id; + String? buyerUserID; + String? buyerName; + int? adsID; + int? unReadMessagesCount; + String? lastMessage; + String? lastMessageDateTime; + + BuyersChatForAdsModel({this.id, this.buyerUserID, this.buyerName, this.adsID}); + + BuyersChatForAdsModel.fromJson(Map json) { + id = json['id']; + buyerUserID = json['buyerUserID']; + buyerName = json['buyerName']; + adsID = json['adsID']; + unReadMessagesCount = json['unReadCount']; + lastMessage = json['lastMessage']; + lastMessageDateTime = json['lastMessageDateTime']; + } +} diff --git a/lib/repositories/ads_repo.dart b/lib/repositories/ads_repo.dart index f7e6ef7..6aa0cd3 100644 --- a/lib/repositories/ads_repo.dart +++ b/lib/repositories/ads_repo.dart @@ -1,19 +1,15 @@ -import 'dart:convert'; -import 'dart:developer'; - import 'package:mc_common_app/api/api_client.dart'; import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/config/dependency_injection.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; -import 'package:mc_common_app/main.dart'; import 'package:mc_common_app/models/advertisment_models/ad_details_model.dart'; import 'package:mc_common_app/models/advertisment_models/ads_bank_details_model.dart'; import 'package:mc_common_app/models/advertisment_models/ads_duration_model.dart'; import 'package:mc_common_app/models/advertisment_models/pdf_receipt_model.dart'; import 'package:mc_common_app/models/advertisment_models/reserved_ads_models.dart'; import 'package:mc_common_app/models/advertisment_models/special_service_model.dart'; -import 'package:mc_common_app/models/advertisment_models/vehicle_details_models.dart'; +import 'package:mc_common_app/models/chat_models/buyers_chat_for_ads_model.dart'; import 'package:mc_common_app/models/general_models/generic_resp_model.dart'; import 'package:mc_common_app/utils/enums.dart'; @@ -26,6 +22,13 @@ abstract class AdsRepo { Future> getAllAds({required bool isMyAds}); + Future> getExploreAdsBasedOnFilters({ + List? cityIdsList, + List? vehicleModelYearIdsList, + List? vehicleBrandIdsList, + List? createdByRolesIdsList, + }); + Future> getMyReservedAds(); Future> getMyAds(); @@ -43,6 +46,8 @@ abstract class AdsRepo { Future createReserveAd({required int adId}); Future uploadBankReceiptsOnReserveDealDone({required int adId, required String detailNote, required List pdfReceiptsList}); + + Future> getChatBuyersForAds({required int adsID}); } class AdsRepoImp implements AdsRepo { @@ -152,7 +157,8 @@ class AdsRepoImp implements AdsRepo { }; var allAdsParams = { "AdsStatuses": ["${AdPostStatus.active.getIdFromAdPostStatusEnum()}"], //only Active ADS - "IsPaid": "true", //only Active ADS + "isActive": "true", //only Active ADS + "isExplore": "true" }; GenericRespModel adsGenericModel = await apiClient.getJsonForObject( @@ -165,6 +171,29 @@ class AdsRepoImp implements AdsRepo { return vehicleAdsDetails; } + @override + Future> getExploreAdsBasedOnFilters( + {List? cityIdsList, List? vehicleModelYearIdsList, List? vehicleBrandIdsList, List? createdByRolesIdsList}) async { + var parameters = { + "CityIDs": cityIdsList ?? [], + "VehicleBrandIDs": vehicleBrandIdsList ?? [], + "VehicleModelYearIDs": vehicleModelYearIdsList ?? [], + "CreatedByRoles": createdByRolesIdsList ?? [], + "AdsStatuses": ["${AdPostStatus.active.getIdFromAdPostStatusEnum()}"], //only Active ADS + "isActive": "true", //only Active ADS + "isExplore": "true" + }; + + GenericRespModel adsGenericModel = await apiClient.getJsonForObject( + token: appState.getUser.data!.accessToken, + (json) => GenericRespModel.fromJson(json), + ApiConsts.vehicleAdsGet, + queryParameters: parameters, + ); + List vehicleAdsDetails = List.generate(adsGenericModel.data.length, (index) => AdDetailsModel.fromJson(adsGenericModel.data[index], false)); + return vehicleAdsDetails; + } + @override Future> getMyReservedAds() async { var params = { @@ -188,9 +217,7 @@ class AdsRepoImp implements AdsRepo { } Future> getAdsPerSpecificIds({required List ids, required List reservedAds}) async { - var params = { - "AdsIDs": ids, - }; + var params = {"AdsIDs": ids, "isActive": "true"}; GenericRespModel adsGenericModel = await apiClient.getJsonForObject( token: appState.getUser.data!.accessToken, (json) => GenericRespModel.fromJson(json), @@ -381,4 +408,20 @@ class AdsRepoImp implements AdsRepo { return Future.value(adsGenericModel); } + + @override + Future> getChatBuyersForAds({required int adsID}) async { + var queryParameters = {"AdsID": adsID.toString()}; + GenericRespModel genericRespModel = await apiClient.getJsonForObject( + (json) => GenericRespModel.fromJson(json), + ApiConsts.getChatBuyersForAds, + queryParameters: queryParameters, + token: appState.getUser.data!.accessToken, + ); + List buyersChatListForAds = []; + if (genericRespModel.data != null && genericRespModel.data.length > 0) { + buyersChatListForAds = List.generate(genericRespModel.data.length, (index) => BuyersChatForAdsModel.fromJson(genericRespModel.data[index])); + } + return buyersChatListForAds; + } } diff --git a/lib/repositories/appointment_repo.dart b/lib/repositories/appointment_repo.dart index d8fa683..1991fef 100644 --- a/lib/repositories/appointment_repo.dart +++ b/lib/repositories/appointment_repo.dart @@ -15,10 +15,10 @@ abstract class AppointmentRepo { Future> getMyAppointmentsForProvider(Map map); Future> getMyAppointmentsForCustomersByFilters({ - List? providerIdsList, - List? categoryIdsList, - List? serviceIdsList, - List? branchIdsList, + List? providerIdsList, + List? categoryIdsList, + List? serviceIdsList, + List? branchIdsList, }); Future updateAppointmentStatus(Map map); @@ -191,48 +191,23 @@ class AppointmentRepoImp implements AppointmentRepo { queryParameters: map, ApiConsts.serviceProvidersAppointmentGet, ); - List appointmentList = await List.generate(genericRespModel.data.length, (index) => AppointmentListModel.fromJson(genericRespModel.data[index])); + List appointmentList = List.generate(genericRespModel.data.length, (index) => AppointmentListModel.fromJson(genericRespModel.data[index])); return appointmentList; } @override Future> getMyAppointmentsForCustomersByFilters({ - List? providerIdsList, - List? categoryIdsList, - List? serviceIdsList, - List? branchIdsList, + List? providerIdsList, + List? categoryIdsList, + List? serviceIdsList, + List? branchIdsList, }) async { - List providerIds = []; - if (providerIdsList != null) { - for (var element in providerIdsList) { - providerIds.add(element.toString()); - } - } - List categoryIds = []; - if (categoryIdsList != null) { - for (var element in categoryIdsList) { - categoryIds.add(element.toString()); - } - } - List serviceIds = []; - if (serviceIdsList != null) { - for (var element in serviceIdsList) { - serviceIds.add(element.toString()); - } - } - List branchIds = []; - if (branchIdsList != null) { - for (var element in branchIdsList) { - branchIds.add(element.toString()); - } - } - var params = { "customerID": appState.getUser.data!.userInfo!.customerId.toString(), - "ServiceProviderIDs": providerIds, - "ProviderBranchIDs": categoryIds, - "ServiceIDs": serviceIds, - "CategoryIDs": categoryIds, + "ServiceProviderIDs": providerIdsList ?? [], + "ProviderBranchIDs": branchIdsList ?? [], + "ServiceIDs": serviceIdsList ?? [], + "CategoryIDs": categoryIdsList ?? [], }; GenericRespModel genericRespModel = await apiClient.getJsonForObject( token: appState.getUser.data!.accessToken, diff --git a/lib/repositories/chat_repo.dart b/lib/repositories/chat_repo.dart index e731c67..7b8b7f7 100644 --- a/lib/repositories/chat_repo.dart +++ b/lib/repositories/chat_repo.dart @@ -8,14 +8,31 @@ import 'package:mc_common_app/config/dependency_injection.dart'; import 'package:mc_common_app/main.dart'; import 'package:mc_common_app/models/chat_models/chat_message_model.dart'; import 'package:mc_common_app/models/general_models/generic_resp_model.dart'; +import 'package:mc_common_app/utils/enums.dart'; import 'package:signalr_core/signalr_core.dart'; abstract class ChatRepo { Future getHubConnection(); - Future markMessageAsRead({required int messageId}); + Future markMessageAsRead({required List messageIds, required ChatTypeEnum chatTypeEnum}); - Future> getUsersChatMessages({required int providerId, required int customerId, required int requestOfferId, required int requestId, int pageIndex = 0, int pageSize = 0}); + Future> getUsersChatMessagesForRequests({ + required int providerId, + required int customerId, + required int requestOfferId, + required int requestId, + int pageIndex = 0, + int pageSize = 0, + }); + + Future> getUsersChatMessagesForAds({ + String? userID, + int? adID, + int? adsChatBuyerId, + required bool isForBuyer, + int pageIndex = 0, + int pageSize = 0, + }); } class ChatRepoImp implements ChatRepo { @@ -41,21 +58,34 @@ class ChatRepoImp implements ChatRepo { } @override - Future markMessageAsRead({required int messageId}) async { - var queryParameters = { - "id": messageId.toString(), - }; - await apiClient.postJsonForObject( + Future markMessageAsRead({required List messageIds, required ChatTypeEnum chatTypeEnum}) async { + String url = ""; + + if (chatTypeEnum == ChatTypeEnum.ads) { + url = ApiConsts.messageIsReadUpdateForAds; + } else if (chatTypeEnum == ChatTypeEnum.requestOffer) { + url = ApiConsts.messageIsReadUpdateForRequests; + } + var queryParameters = {"iDs": messageIds}; + GenericRespModel genericRespModel = await apiClient.postJsonForObject( (json) => GenericRespModel.fromJson(json), - ApiConsts.messageIsReadUpdate, + url, queryParameters, token: appState.getUser.data!.accessToken, ); + + return genericRespModel.message == ""; } @override - Future> getUsersChatMessages( - {required int providerId, required int customerId, required int requestOfferId, required int requestId, int pageIndex = 0, int pageSize = 0}) async { + Future> getUsersChatMessagesForRequests({ + required int providerId, + required int customerId, + required int requestOfferId, + required int requestId, + int pageIndex = 0, + int pageSize = 0, + }) async { var queryParameters = { "ReqOfferID": requestOfferId.toString(), "RequestID": requestId.toString(), @@ -66,7 +96,41 @@ class ChatRepoImp implements ChatRepo { }; GenericRespModel genericRespModel = await apiClient.getJsonForObject( (json) => GenericRespModel.fromJson(json), - ApiConsts.getChatMessages, + ApiConsts.getChatMessagesForRequests, + queryParameters: queryParameters, + token: appState.getUser.data!.accessToken, + ); + if (genericRespModel.messageStatus == 1 && genericRespModel.data != null) { + List chatMessages = List.generate( + genericRespModel.data.length, + (index) => ChatMessageModel.fromJson(genericRespModel.data[index]), + ); + return chatMessages; + } + return []; + } + + @override + Future> getUsersChatMessagesForAds({String? userID, int? adID, int? adsChatBuyerId, required bool isForBuyer, int pageIndex = 0, int pageSize = 0}) async { + var parameterForBuyer = { + "UserID": userID.toString(), + "AdsID": adID.toString(), + "IsAdsBuyer": isForBuyer.toString(), + "PageSize": pageSize.toString(), + "PageIndex": pageIndex.toString(), + }; + + var parameterForSeller = { + "AdsChatBuyerID": adsChatBuyerId.toString(), + "IsAdsBuyer": isForBuyer.toString(), + "PageSize": pageSize.toString(), + "PageIndex": pageIndex.toString(), + }; + + var queryParameters = isForBuyer ? parameterForBuyer : parameterForSeller; + GenericRespModel genericRespModel = await apiClient.getJsonForObject( + (json) => GenericRespModel.fromJson(json), + ApiConsts.getChatMessagesForAds, queryParameters: queryParameters, token: appState.getUser.data!.accessToken, ); diff --git a/lib/repositories/user_repo.dart b/lib/repositories/user_repo.dart index 7856020..75a7500 100644 --- a/lib/repositories/user_repo.dart +++ b/lib/repositories/user_repo.dart @@ -37,7 +37,7 @@ abstract class UserRepo { Future loginV2OTP(String userToken, String loginType); - Future loginV2OTPVerify(String userToken, String otp); + Future loginV2OTPVerify(String userToken, String otp, String deviceType, String deviceToken); Future refreshTokenAPI(String token, String refreshToken); @@ -142,8 +142,13 @@ class UserRepoImp implements UserRepo { } @override - Future loginV2OTPVerify(String userToken, String otp) async { - var postParams = {"userToken": userToken, "userOTP": otp}; + Future loginV2OTPVerify( + String userToken, + String otp, + String deviceType, + String deviceToken, + ) async { + var postParams = {"userToken": userToken, "userOTP": otp, "deviceType": deviceType, "deviceToken": deviceToken}; return await injector.get().postJsonForResponse(ApiConsts.Login_V2_OTPVerify, postParams); } diff --git a/lib/services/firebase_service.dart b/lib/services/firebase_service.dart index 8320373..3d8a22e 100644 --- a/lib/services/firebase_service.dart +++ b/lib/services/firebase_service.dart @@ -41,6 +41,7 @@ class FirebaseMessagingServiceImp implements FirebaseMessagingService { Future initializeNotifications() async { await requestPermissions(); AppState().setDeviceToken = await getFirebaseToken(); + AppState().setDeviceType = Platform.isAndroid ? "1" : "2"; await Permission.notification.isDenied.then((bool value) { if (value) { Permission.notification.request(); diff --git a/lib/view_models/ad_view_model.dart b/lib/view_models/ad_view_model.dart index 52d3d48..d18836f 100644 --- a/lib/view_models/ad_view_model.dart +++ b/lib/view_models/ad_view_model.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'dart:developer'; import 'dart:io'; import 'package:flutter/cupertino.dart'; import 'package:mc_common_app/classes/app_state.dart'; @@ -16,6 +17,8 @@ import 'package:mc_common_app/models/advertisment_models/ss_car_check_schedule_m import 'package:mc_common_app/models/advertisment_models/ss_photo_schedule_model.dart'; import 'package:mc_common_app/models/advertisment_models/vehicle_details_models.dart'; import 'package:mc_common_app/models/appointments_models/service_schedule_model.dart'; +import 'package:mc_common_app/models/chat_models/buyers_chat_for_ads_model.dart'; +import 'package:mc_common_app/models/chat_models/chat_message_model.dart'; import 'package:mc_common_app/models/general_models/enums_model.dart'; import 'package:mc_common_app/models/general_models/generic_resp_model.dart'; import 'package:mc_common_app/models/general_models/widgets_models.dart'; @@ -27,8 +30,10 @@ import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/utils/navigator.dart'; import 'package:mc_common_app/utils/utils.dart'; import 'package:mc_common_app/view_models/base_view_model.dart'; +import 'package:mc_common_app/view_models/chat_view_model.dart'; import 'package:mc_common_app/widgets/dropdown/dropdow_field.dart'; import 'package:easy_localization/easy_localization.dart'; +import 'package:provider/provider.dart'; class AdVM extends BaseVM { final CommonRepo commonRepo; @@ -151,8 +156,8 @@ class AdVM extends BaseVM { isExploreAdsTapped = value; //To show the Active Ads - applyFilterOnMyAds(adPostStatusEnum: AdPostStatus.allAds); - applyFilterOnExploreAds(createdByRoleFilter: CreatedByRoleEnum.allAds); + // applyFilterOnMyAds(adPostStatusEnum: AdPostStatus.allAds); + // applyFilterOnExploreAds(createdByRoleFilter: CreatedByRoleEnum.allAds); // if (value) { // await getExploreAds(); // } @@ -170,6 +175,8 @@ class AdVM extends BaseVM { if (myAdsFilterOptions.isNotEmpty && exploreAdsFilterOptions.isNotEmpty) { return; } + log("myAdsEnums: ${myAdsEnums.length}"); + log("exploreAdsEnums: ${exploreAdsEnums.length}"); if (myAdsEnums.isEmpty) { myAdsEnums = await commonRepo.getEnumTypeValues(enumTypeID: AppEnums.myAdsFilterEnumId); } @@ -1471,6 +1478,7 @@ class AdVM extends BaseVM { // ************ ADS SEARCH VIEW **************** Future populateDataForAdFilter() async { + setState(ViewState.busy); if (vehicleBrands.isEmpty) { vehicleBrands = await commonRepo.getVehicleBrands(vehicleTypeId: -1); } @@ -1478,6 +1486,7 @@ class AdVM extends BaseVM { vehicleModelYears = await commonRepo.getVehicleModelYears(vehicleTypeId: -1); } vehicleCities = await commonRepo.getVehicleCities(countryId: -1); // fetch all the cities + setState(ViewState.idle); } ifAlreadyExist({required List list, required DropValue value}) { @@ -1546,8 +1555,8 @@ class AdVM extends BaseVM { void updateSelectionVehicleAdOwnerId(SelectionModel id, {bool isForSearch = false}) { if (isForSearch) { - EnumsModel owner = exploreAdsEnums.firstWhere((element) => element.id == id.selectedId); - DropValue ownerValue = DropValue(owner.id, "${owner.enumValueStr} Ads", ""); + EnumsModel owner = exploreAdsEnums.firstWhere((element) => element.enumValue == id.selectedId); + DropValue ownerValue = DropValue(owner.enumValue, "${owner.enumValueStr} Ads", ""); if (!ifAlreadyExist(list: vehicleYearAdSearchHistory, value: ownerValue)) { addToVehicleAdOwnerSearchHistory(value: ownerValue); } @@ -1617,44 +1626,54 @@ class AdVM extends BaseVM { vehicleAdOwnerSearchHistory.clear(); vehicleLocationAdSearchHistory.clear(); vehicleYearAdSearchHistory.clear(); + adsFiltersCounter = 0; + getExploreAds(); notifyListeners(); } + void clearAdFilterSelections() { + vehicleCityId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); + vehicleBrandId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); + vehicleModelYearId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); + vehicleOwnerId = SelectionModel(selectedOption: "", selectedId: -1, errorValue: ""); + } + Future getAdsBasedOnFilters() async { - exploreAds.clear(); + exploreAdsFilteredList.clear(); setState(ViewState.busy); - List cityIdsList = []; + List cityIdsList = []; if (vehicleLocationAdSearchHistory.isNotEmpty) { for (var element in vehicleLocationAdSearchHistory) { - cityIdsList.add(element.id); + cityIdsList.add(element.id.toString()); } } - List brandsIdsList = []; + List brandsIdsList = []; if (vehicleBrandsAdSearchHistory.isNotEmpty) { for (var element in vehicleBrandsAdSearchHistory) { - brandsIdsList.add(element.id); + brandsIdsList.add(element.id.toString()); } } - List vehicleYearIdsList = []; + + List vehicleYearIdsList = []; if (vehicleYearAdSearchHistory.isNotEmpty) { for (var element in vehicleYearAdSearchHistory) { - vehicleYearIdsList.add(element.id); + vehicleYearIdsList.add(element.id.toString()); } } - List adOwnerIdsList = []; + + List adOwnerIdsList = []; if (vehicleAdOwnerSearchHistory.isNotEmpty) { for (var element in vehicleAdOwnerSearchHistory) { - adOwnerIdsList.add(element.id); + adOwnerIdsList.add(element.id.toString()); } } - // - // myAppointments = await appointmentRepo.getMyAppointmentsForCustomersByFilters( - // providerIdsList: providersIdsList.isNotEmpty ? providersIdsList : null, - // categoryIdsList: categoryIdsList.isNotEmpty ? categoryIdsList : null, - // serviceIdsList: servicesIdsList.isNotEmpty ? servicesIdsList : null, - // branchIdsList: branchesIdsList.isNotEmpty ? branchesIdsList : null, - // ); - applyFilterOnExploreAds(createdByRoleFilter: CreatedByRoleEnum.allAds); + + exploreAdsFilteredList = await adsRepo.getExploreAdsBasedOnFilters( + cityIdsList: cityIdsList, + createdByRolesIdsList: adOwnerIdsList, + vehicleBrandIdsList: brandsIdsList, + vehicleModelYearIdsList: vehicleYearIdsList, + ); setState(ViewState.idle); } @@ -1809,15 +1828,46 @@ class AdVM extends BaseVM { return specialServiceCards.indexWhere((element) => element.serviceSelectedId!.selectedId == id); } - void onMessagesButtonPressed({required BuildContext context, required AdDetailsModel adDetailsModel}) { - ChatViewArgumentsForAd chatViewArgumentsForAd = ChatViewArgumentsForAd(adDetailsModel: adDetailsModel); + List buyersChatListForAds = []; - ChatViewArguments chatViewArguments = ChatViewArguments(chatTypeEnum: ChatTypeEnum.ads, chatViewArgumentsForAd: chatViewArgumentsForAd); - navigateWithName(context, AppRoutes.chatView, arguments: chatViewArguments); + void onMessagesButtonPressed({required BuildContext context, required AdDetailsModel adDetailsModel}) async { + final myUserID = AppState().getUser.data!.userInfo!.userId; + if (adDetailsModel.isMyAd != null && adDetailsModel.isMyAd!) { + await getBuyerChatsByAds(adsID: adDetailsModel.id!, context: context); + navigateWithName(context, AppRoutes.adsBuyerChatsListView, arguments: buyersChatListForAds); + } else { + ChatViewArgumentsForAd chatViewArgumentsForAd = ChatViewArgumentsForAd(receiverUserID: adDetailsModel.userID, adsID: adDetailsModel.id); + ChatViewArguments chatViewArguments = ChatViewArguments(chatTypeEnum: ChatTypeEnum.ads, chatViewArgumentsForAd: chatViewArgumentsForAd); + final chatVM = context.read(); + await chatVM + .getUsersChatMessagesForAd( + context: context, + isForBuyer: true, + adsChatBuyerId: 1, + adID: adDetailsModel.id, + userID: myUserID, + ) + .whenComplete( + () => navigateWithName(context, AppRoutes.chatView, arguments: chatViewArguments), + ); + } } -} -// Edit Work End Amir + Future getBuyerChatsByAds({required int adsID, required BuildContext context}) async { + try { + Utils.showLoading(context); + List buyersChatList = await adsRepo.getChatBuyersForAds(adsID: adsID); + Utils.hideLoading(context); + buyersChatListForAds.clear(); + buyersChatListForAds = buyersChatList; + notifyListeners(); + } catch (e) { + logger.i(e.toString()); + Utils.showToast(e.toString()); + Utils.hideLoading(context); + } + } +} class VehicleDamageCard { List? partImages; diff --git a/lib/view_models/appointments_view_model.dart b/lib/view_models/appointments_view_model.dart index c184177..72948eb 100644 --- a/lib/view_models/appointments_view_model.dart +++ b/lib/view_models/appointments_view_model.dart @@ -238,9 +238,7 @@ class AppointmentsVM extends BaseVM { } void removeServiceInCurrentAppointment(int index) { - int serviceId = servicesInCurrentAppointment - .elementAt(index) - .serviceProviderServiceId ?? -1; + int serviceId = servicesInCurrentAppointment.elementAt(index).serviceProviderServiceId ?? -1; allSelectedItemsInAppointments.removeWhere((element) => element.serviceProviderServiceId == serviceId); servicesInCurrentAppointment.removeAt(index); notifyListeners(); @@ -275,8 +273,6 @@ class AppointmentsVM extends BaseVM { // TODO: THIS SHOULD REMOVED AND ADDED IN THE ENUMS API appointmentsFilterOptions.add(FilterListModel(title: "Work In Progress", isSelected: false, id: 7)); appointmentsFilterOptions.add(FilterListModel(title: "Visit Completed", isSelected: false, id: 8)); - - logger.i("appointmentsFilterOptions: ${appointmentsFilterOptions.length}"); notifyListeners(); } @@ -363,7 +359,8 @@ class AppointmentsVM extends BaseVM { myAppointments = await appointmentRepo.getMyAppointmentsForCustomersByFilters(); // myFilteredAppointments = myAppointments; - myUpComingAppointments = myAppointments.where((element) => element.appointmentStatusEnum == AppointmentStatusEnum.booked || element.appointmentStatusEnum == AppointmentStatusEnum.confirmed ).toList(); + myUpComingAppointments = + myAppointments.where((element) => element.appointmentStatusEnum == AppointmentStatusEnum.booked || element.appointmentStatusEnum == AppointmentStatusEnum.confirmed).toList(); setState(ViewState.idle); applyFilterOnAppointmentsVM(appointmentStatusEnum: AppointmentStatusEnum.allAppointments); notifyListeners(); @@ -391,7 +388,7 @@ class AppointmentsVM extends BaseVM { setState(ViewState.busy); myAppointments = await appointmentRepo.getMyAppointmentsForProvider(map); myFilteredAppointments = myAppointments; - myUpComingAppointments = await myAppointments.where((element) => element.appointmentStatusEnum == AppointmentStatusEnum.confirmed).toList(); + myUpComingAppointments = myAppointments.where((element) => element.appointmentStatusEnum == AppointmentStatusEnum.confirmed).toList(); applyFilterOnAppointmentsVM(appointmentStatusEnum: AppointmentStatusEnum.allAppointments, isNeedCustomerFilter: true); setState(ViewState.idle); } @@ -594,7 +591,7 @@ class AppointmentsVM extends BaseVM { isScrollControlled: true, enableDrag: true, builder: (BuildContext context) { - return AppointmentServicePickBottomSheet(); + return const AppointmentServicePickBottomSheet(); }, ); } @@ -657,8 +654,8 @@ class AppointmentsVM extends BaseVM { crossAxisAlignment: CrossAxisAlignment.end, children: [ (selectedService.isHomeSelected - ? "${(selectedService.currentTotalServicePrice) + (double.parse((selectedService.rangePricePerKm ?? "0.0")) * totalKms)}" - : "${selectedService.currentTotalServicePrice}") + ? "${(selectedService.currentTotalServicePrice) + (double.parse((selectedService.rangePricePerKm ?? "0.0")) * totalKms)}" + : "${selectedService.currentTotalServicePrice}") .toText(fontSize: 29, isBold: true), 2.width, LocaleKeys.sar.tr().toText(color: MyColors.lightTextColor, fontSize: 16, isBold: true).paddingOnly(bottom: 5), @@ -808,6 +805,7 @@ class AppointmentsVM extends BaseVM { // BRANCHES RELATED List nearbyBranches = []; + List myRecentBranches = []; BranchDetailModel? selectedBranchModel; List branchServices = []; @@ -852,6 +850,13 @@ class AppointmentsVM extends BaseVM { setState(ViewState.idle); } + Future getMyRecentBranches({bool isNeedToRebuild = false}) async { + myRecentBranches.clear(); + if (isNeedToRebuild) setState(ViewState.busy); + myRecentBranches = await branchRepo.getAllNearBranchAndServices(); + setState(ViewState.idle); + } + void getBranchCategories() async { for (var value in selectedBranchModel!.branchServices!) { if (!isCategoryAlreadyPresent(value.categoryId!)) { @@ -1081,10 +1086,10 @@ class AppointmentsVM extends BaseVM { DropValue( element.id ?? 0, ((element.categoryName!.isEmpty - ? "N/A" - : countryCode == "SA" - ? element.categoryNameN - : element.categoryName) ?? + ? "N/A" + : countryCode == "SA" + ? element.categoryNameN + : element.categoryName) ?? "N/A"), ""), ); @@ -1388,42 +1393,42 @@ class AppointmentsVM extends BaseVM { appointmentFilterBranchSearchHistory.clear(); appointmentFiltersCounter = 0; clearAppointmentFilterSelections(); + getMyAppointments(); notifyListeners(); } Future getAppointmentsBasedOnFilters() async { - nearbyBranches.clear(); setState(ViewState.busy); - List providersIdsList = []; + List providersIdsList = []; if (appointmentFilterProviderSearchHistory.isNotEmpty) { for (var element in appointmentFilterProviderSearchHistory) { - providersIdsList.add(element.id); + providersIdsList.add(element.id.toString()); } } - List categoryIdsList = []; + List categoryIdsList = []; if (appointmentFilterCategorySearchHistory.isNotEmpty) { for (var element in appointmentFilterCategorySearchHistory) { - categoryIdsList.add(element.id); + categoryIdsList.add(element.id.toString()); } } - List servicesIdsList = []; + List servicesIdsList = []; if (appointmentFilterServicesSearchHistory.isNotEmpty) { for (var element in appointmentFilterServicesSearchHistory) { - servicesIdsList.add(element.id); + servicesIdsList.add(element.id.toString()); } } - List branchesIdsList = []; + List branchesIdsList = []; if (appointmentFilterBranchSearchHistory.isNotEmpty) { for (var element in appointmentFilterBranchSearchHistory) { - branchesIdsList.add(element.id); + branchesIdsList.add(element.id.toString()); } } myAppointments = await appointmentRepo.getMyAppointmentsForCustomersByFilters( - providerIdsList: providersIdsList.isNotEmpty ? providersIdsList : null, - categoryIdsList: categoryIdsList.isNotEmpty ? categoryIdsList : null, - serviceIdsList: servicesIdsList.isNotEmpty ? servicesIdsList : null, - branchIdsList: branchesIdsList.isNotEmpty ? branchesIdsList : null, + providerIdsList: providersIdsList, + categoryIdsList: categoryIdsList, + serviceIdsList: servicesIdsList, + branchIdsList: branchesIdsList, ); applyFilterOnAppointmentsVM(appointmentStatusEnum: AppointmentStatusEnum.allAppointments); setState(ViewState.idle); diff --git a/lib/view_models/chat_view_model.dart b/lib/view_models/chat_view_model.dart index 8e4b8d2..4a88a55 100644 --- a/lib/view_models/chat_view_model.dart +++ b/lib/view_models/chat_view_model.dart @@ -8,7 +8,6 @@ import 'package:mc_common_app/classes/consts.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/main.dart'; -import 'package:mc_common_app/models/advertisment_models/ad_details_model.dart'; import 'package:mc_common_app/models/chat_models/chat_message_model.dart'; import 'package:mc_common_app/models/general_models/generic_resp_model.dart'; import 'package:mc_common_app/models/requests_models/provider_offers_model.dart'; @@ -56,7 +55,6 @@ class ChatVM extends ChangeNotifier { return; } - logger.i(scrollController.position.maxScrollExtent); scrollController.animateTo( scrollController.position.maxScrollExtent + 200, // for the text field duration: const Duration(seconds: 1), @@ -130,7 +128,7 @@ class ChatVM extends ChangeNotifier { return isValidated; } - Future onNewMessageReceived({required List messages, bool isMyOwnOffer = false, required RequestsVM requestsVM}) async { + Future onNewMessageReceivedForRequestOffer({required List messages, bool isMyOwnOffer = false, required RequestsVM requestsVM}) async { if (AppState().currentAppType == AppType.customer) { for (var msg in messages) { int providerIndex = serviceProviderOffersList.indexWhere((element) => element.providerUserId == msg.senderUserID); @@ -159,33 +157,55 @@ class ChatVM extends ChangeNotifier { notifyListeners(); } + Future onNewMessageReceivedForAds({required List messages}) async { + for (var msg in messages) { + currentMessagesForAds.add(msg); + } + scrollChatDown(); + notifyListeners(); + } + + void subscribeToReceiveRequestOfferMessages(BuildContext context) { + hubConnection!.on(SignalrConsts.receiveMessageRequestOffer, (List? arguments) { + if (arguments == null || arguments.isEmpty) return; + List chat = []; + for (var message in arguments) { + final chatMessage = ChatMessageModel.fromJson(message as Map); + chat.add(chatMessage); + } + onNewMessageReceivedForRequestOffer(messages: chat, requestsVM: context.read()); + logger.i(arguments); + // Utils.showToast(arguments.toString()); + }); + } + + void subscribeToReceiveAdMessages(BuildContext context) { + hubConnection!.on(SignalrConsts.receiveMessageAds, (List? arguments) { + if (arguments == null || arguments.isEmpty) return; + List chat = []; + for (var message in arguments) { + final chatMessage = ChatMessageModel.fromJson(message as Map); + chat.add(chatMessage); + } + onNewMessageReceivedForAds(messages: chat); + logger.i(arguments); + // Utils.showToast(arguments.toString()); + }); + } + Future buildHubConnection(BuildContext context) async { if (hubConnection == null || hubConnection!.state != HubConnectionState.connected) { try { hubConnection = await chatRepo.getHubConnection(); await hubConnection!.start(); - hubConnection!.on(SignalrConsts.receiveMessageRequestOffer, (List? arguments) { - if (arguments == null || arguments.isEmpty) return; - List chat = []; - for (var message in arguments) { - final chatMessage = ChatMessageModel.fromJson(message as Map); - chat.add(chatMessage); - } - onNewMessageReceived(messages: chat, requestsVM: context.read()); - logger.i(arguments); - Utils.showToast(arguments.toString()); - }); - + subscribeToReceiveRequestOfferMessages(context); + subscribeToReceiveAdMessages(context); hubConnection!.onclose((exception) { logger.i("onClose: ${exception.toString()}"); buildHubConnection(context); }); - hubConnection!.onreconnecting((exception) => () { - logger.i("onReconnecting: ${exception.toString()}"); - }); - hubConnection!.onreconnected((connectionId) => () { - logger.i("onReconnected: ${connectionId.toString()}"); - }); + hubConnection!.onreconnecting((exception) => () => logger.i("onReconnecting: ${exception.toString()}")); + hubConnection!.onreconnected((connectionId) => () => logger.i("onReconnected: ${connectionId.toString()}")); } catch (e) { logger.i("Error: ${e.toString()}"); } @@ -208,24 +228,25 @@ class ChatVM extends ChangeNotifier { } if (hubConnection!.state == HubConnectionState.connected) { final providerId = AppState().getUser.data!.userInfo!.providerId; + final obj = { + "ReceiverUserID": receiverId, + "MessageType": chatMessageType.getIdFromChatMessageTypeEnum(), + "ChatText": message, + "RequestID": requestId, + "ReqOfferID": 0, + "ReqOffer": { + "RequestID": requestId, + "Price": double.parse(offerPrice), + "ServiceProviderID": providerId, + "OfferStatus": RequestOfferStatusEnum.offer.getIdFromRequestOfferStatusEnum(), + "Comment": message, + }, + }; + logger.i(obj); + hubConnection!.invoke( SignalrConsts.sendMessageRequestOffer, - args: [ - { - "ReceiverUserID": receiverId, - "MessageType": chatMessageType.getIdFromChatMessageTypeEnum(), - "ChatText": message, - "RequestID": requestId, - "ReqOfferID": 0, - "ReqOffer": { - "RequestID": requestId, - "Price": double.parse(offerPrice), - "ServiceProviderID": providerId, - "OfferStatus": RequestOfferStatusEnum.offer.getIdFromRequestOfferStatusEnum(), - "Comment": message, - }, - } - ], + args: [obj], ).catchError((e) { logger.i("error in invoking SendMessageRequestOffer: ${e.toString()}"); Utils.showToast(e.toString()); @@ -233,22 +254,6 @@ class ChatVM extends ChangeNotifier { }); } - logger.i({ - "ID": "", //here should be req offer ID - "ReceiverUserID": receiverId, - "MessageType": chatMessageType.getIdFromChatMessageTypeEnum(), - "ChatText": message, - "RequestID": requestId, - "ReqOfferID": 0, - "ReqOffer": { - "ID": "", - "RequestID": requestId, - "Price": double.parse(offerPrice), - "ServiceProviderID": AppState().getUser.data!.userInfo!.providerId, - "OfferStatus": RequestOfferStatusEnum.offer.getIdFromRequestOfferStatusEnum(), - "Comment": message, - }, - }); return true; } @@ -271,7 +276,7 @@ class ChatVM extends ChangeNotifier { final userId = AppState().getUser.data!.userInfo!.userId.toString(); final name = AppState().getUser.data!.userInfo!.firstName.toString(); - logger.i(({ + final obj = { "ReceiverUserID": receiverId, "SenderUserID": userId, "MessageType": chatMessageType.getIdFromChatMessageTypeEnum(), @@ -279,21 +284,12 @@ class ChatVM extends ChangeNotifier { "RequestID": requestId, "ReqOfferID": latestOfferId, // "ReqOffer": {} - })); + }; + logger.i(obj); hubConnection!.invoke( SignalrConsts.sendMessageRequestOffer, - args: [ - { - "ReceiverUserID": receiverId, - "SenderUserID": userId, - "MessageType": chatMessageType.getIdFromChatMessageTypeEnum(), - "ChatText": message, - "RequestID": requestId, - "ReqOfferID": latestOfferId, - // "ReqOffer": {} - } - ], + args: [obj], ).catchError((e) { logger.i("error in invoking SendMessage: ${e.toString()}"); Utils.showToast(e.toString()); @@ -355,7 +351,7 @@ class ChatVM extends ChangeNotifier { try { int customerId = AppState().getUser.data!.userInfo!.customerId!; Utils.showLoading(context); - List chatMessages = await chatRepo.getUsersChatMessages(providerId: providerId, customerId: customerId, requestOfferId: requestOfferId, requestId: requestId); + List chatMessages = await chatRepo.getUsersChatMessagesForRequests(providerId: providerId, customerId: customerId, requestOfferId: requestOfferId, requestId: requestId); serviceProviderOffersList[providerOfferIndex].chatMessages = chatMessages; if (serviceProviderOffersList[providerOfferIndex].chatMessages != null) { for (var message in serviceProviderOffersList[providerOfferIndex].chatMessages!) { @@ -384,7 +380,7 @@ class ChatVM extends ChangeNotifier { try { int providerId = AppState().getUser.data!.userInfo!.providerId!; Utils.showLoading(context); - List chatMessages = await chatRepo.getUsersChatMessages(providerId: providerId, customerId: customerId, requestOfferId: requestOfferId, requestId: requestId); + List chatMessages = await chatRepo.getUsersChatMessagesForRequests(providerId: providerId, customerId: customerId, requestOfferId: requestOfferId, requestId: requestId); context.read().overwriteChatMessagesInRequestsModel(messages: chatMessages, index: customerRequestIndex, context: context); Utils.hideLoading(context); } catch (e) { @@ -424,25 +420,26 @@ class ChatVM extends ChangeNotifier { await buildHubConnection(context); } if (hubConnection!.state == HubConnectionState.connected) { + var obj = { + "ReceiverUserID": receiverId, + "MessageType": chatMessageType.getIdFromChatMessageTypeEnum(), + "ChatText": comments, + "RequestID": requestId, + "ReqOfferID": requestOfferID, + "ReqOffer": { + "ID": requestOfferID, + "RequestID": requestId, + "Price": double.parse(offerPrice), + "ServiceProviderID": serviceProviderID, + "OfferStatus": requestOfferStatusEnum.getIdFromRequestOfferStatusEnum(), + "Comment": comments, + }, + }; + logger.i(obj); + hubConnection!.invoke( SignalrConsts.sendMessageRequestOffer, - args: [ - { - "ReceiverUserID": receiverId, - "MessageType": chatMessageType.getIdFromChatMessageTypeEnum(), - "ChatText": comments, - "RequestID": requestId, - "ReqOfferID": requestOfferID, - "ReqOffer": { - "ID": requestOfferID, - "RequestID": requestId, - "Price": double.parse(offerPrice), - "ServiceProviderID": serviceProviderID, - "OfferStatus": requestOfferStatusEnum.getIdFromRequestOfferStatusEnum(), - "Comment": comments, - }, - } - ], + args: [obj], ).catchError((e) { logger.i("error in invoking SendMessageRequestOffer: ${e.toString()}"); Utils.showToast(e.toString()); @@ -450,31 +447,59 @@ class ChatVM extends ChangeNotifier { }); } - logger.i({ - "ReceiverUserID": receiverId, - "MessageType": chatMessageType.getIdFromChatMessageTypeEnum(), - "ChatText": comments, - "RequestID": requestId, - "ReqOfferID": 0, - "ReqOffer": { - "ID": requestOfferID, - "RequestID": requestId, - "Price": double.parse(offerPrice), - "ServiceProviderID": serviceProviderID, - "OfferStatus": requestOfferStatusEnum.getIdFromRequestOfferStatusEnum(), - "Comment": comments, - }, - }); return true; } // =================== Ads ====================== + List currentMessagesForAds = []; + + Future getUsersChatMessagesForAd({required BuildContext context, int? adID, int? adsChatBuyerId, String? userID, required bool isForBuyer}) async { + try { + Utils.showLoading(context); + currentMessagesForAds = await chatRepo.getUsersChatMessagesForAds(userID: userID, adID: adID, isForBuyer: isForBuyer, adsChatBuyerId: adsChatBuyerId); + Utils.hideLoading(context); + + List unreadMessageIds = []; + + for (var msg in currentMessagesForAds) { + if (!msg.isRead!) { + unreadMessageIds.add(msg.id!); + } + } + + if (unreadMessageIds.isNotEmpty) { + await markMessagesAsRead(context, unreadMessageIds, ChatTypeEnum.ads); + } + + notifyListeners(); + } catch (e) { + logger.i(e.toString()); + Utils.showToast(e.toString()); + Utils.hideLoading(context); + } + } + + Future markMessagesAsRead(BuildContext context, List messageIds, ChatTypeEnum chatTypeEnum) async { + bool status = false; + try { + Utils.showLoading(context); + status = await chatRepo.markMessageAsRead(messageIds: messageIds, chatTypeEnum: chatTypeEnum); + Utils.hideLoading(context); + } catch (e) { + logger.i(e.toString()); + Utils.showToast(e.toString()); + Utils.hideLoading(context); + status = false; + } + return status; + } + Future onTextMessageSendForAds({ required String receiverId, required ChatMessageTypeEnum chatMessageType, required String message, - required AdDetailsModel adDetailsModel, + required int adId, required BuildContext context, }) async { if (message.isEmpty) return false; @@ -487,18 +512,18 @@ class ChatVM extends ChangeNotifier { if (hubConnection!.state == HubConnectionState.connected) { final userId = AppState().getUser.data!.userInfo!.userId.toString(); final name = AppState().getUser.data!.userInfo!.firstName.toString(); + final obj = { + "ReceiverUserID": receiverId, + // "SenderUserID": userId, + "MessageType": chatMessageType.getIdFromChatMessageTypeEnum(), + "ChatText": message, + "AdsID": adId, + }; + logger.i("$obj"); hubConnection!.invoke( SignalrConsts.sendMessageAds, - args: [ - { - "ReceiverUserID": receiverId, - "SenderUserID": userId, - "MessageType": chatMessageType.getIdFromChatMessageTypeEnum(), - "ChatText": message, - "AdsID": adDetailsModel.id, - } - ], + args: [obj], ).catchError((e) { logger.i("error in invoking SendMessage: ${e.toString()}"); Utils.showToast(e.toString()); @@ -509,26 +534,18 @@ class ChatVM extends ChangeNotifier { messageType: chatMessageType.getIdFromChatMessageTypeEnum(), chatText: message, isMyMessage: true, - requestID: 0, senderName: name, senderUserID: userId, chatMessageTypeEnum: ChatMessageTypeEnum.freeText, receiverUserID: receiverId, ); - if (AppState().currentAppType == AppType.customer) { - - - - - - - } else { - - + currentMessagesForAds.add(chatMessageModel); + notifyListeners(); - } + if (AppState().currentAppType == AppType.customer) { + } else {} return true; } return false; diff --git a/lib/view_models/dashboard_view_model_customer.dart b/lib/view_models/dashboard_view_model_customer.dart index 2bebc2a..97e0b67 100644 --- a/lib/view_models/dashboard_view_model_customer.dart +++ b/lib/view_models/dashboard_view_model_customer.dart @@ -1,3 +1,4 @@ +import 'dart:developer'; import 'dart:io'; import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/config/dependency_injection.dart'; @@ -30,7 +31,7 @@ class DashboardVmCustomer extends BaseVM { int selectedNavbarBarIndex = 2; void onNavbarTapped(int index) async { - print(AppState().getDeviceToken); + logger.i(AppState().getDeviceToken); selectedNavbarBarIndex = index; notifyListeners(); } @@ -60,54 +61,62 @@ class DashboardVmCustomer extends BaseVM { } } - onInitState(BuildContext context) async { - Future.wait([ - context.read().populateRequestsFilterList(), - context.read().populateAppointmentsFilterList(), - context.read().populateBranchesFilterList(), - context.read().populateAdsFilterList(), - ]); - } - Future onRefresh(BuildContext context) async { AdVM adVM = Provider.of(context, listen: false); AppointmentsVM appointmentsVM = Provider.of(context, listen: false); RequestsVM requestsVM = Provider.of(context, listen: false); ChatVM chatVM = Provider.of(context, listen: false); - if (appointmentsVM.myAppointments.isEmpty) { - await appointmentsVM.getMyAppointments(); - } + appointmentsVM.populateBranchesFilterList(); + appointmentsVM.populateAppointmentsFilterList(); + adVM.populateAdsFilterList(); + requestsVM.populateRequestsFilterList(); - if (appointmentsVM.nearbyBranches.isEmpty) { - await appointmentsVM.applyFilterOnBranches(index: 0); // to get all branches! - } - - if (adVM.myAds.isEmpty) { - await adVM.getMyAds(); - } - if (adVM.exploreAds.isEmpty) { - await adVM.getExploreAds(); - } - if (requestsVM.myRequests.isEmpty) { - await requestsVM.getRequests(appType: AppType.customer); - } - - if (adVM.vehicleTypes.isEmpty) { - await adVM.getVehicleTypes(); - } + await appointmentsVM.getMyAppointments(); + await appointmentsVM.applyFilterOnBranches(index: 0); // to get all branches! + await appointmentsVM.getMyRecentBranches(); // to get my recent branches! + await adVM.getMyAds(); + await adVM.getExploreAds(); + await requestsVM.getRequests(appType: AppType.customer); + await adVM.getVehicleTypes(); + await adVM.getVehicleAdsDuration(); + await chatVM.buildHubConnection(context); - if (adVM.vehicleAdsDurations.isEmpty) { - await adVM.getVehicleAdsDuration(); - } + // if (appointmentsVM.myAppointments.isEmpty) { + // await appointmentsVM.getMyAppointments(); + // } + // + // if (appointmentsVM.nearbyBranches.isEmpty) { + // await appointmentsVM.applyFilterOnBranches(index: 0); // to get all branches! + // } + // if (appointmentsVM.myRecentBranches.isEmpty) { + // await appointmentsVM.getMyRecentBranches(); // to get my recent branches! + // } + // + // if (adVM.myAds.isEmpty) { + // await adVM.getMyAds(); + // } + // if (adVM.exploreAds.isEmpty) { + // await adVM.getExploreAds(); + // } + // if (requestsVM.myRequests.isEmpty) { + // await requestsVM.getRequests(appType: AppType.customer); + // } + // + // if (adVM.vehicleTypes.isEmpty) { + // await adVM.getVehicleTypes(); + // } + // + // if (adVM.vehicleAdsDurations.isEmpty) { + // await adVM.getVehicleAdsDuration(); + // } - await chatVM.buildHubConnection(context); - adVM.updateVehicleAdDurationId( - SelectionModel( - selectedId: adVM.vehicleAdsDurations.first.id ?? 0, - selectedOption: "${adVM.vehicleAdsDurations.first.days} Days", - itemPrice: adVM.vehicleAdsDurations.first.price!.toInt().toString(), - ), - ); + // adVM.updateVehicleAdDurationId( + // SelectionModel( + // selectedId: adVM.vehicleAdsDurations.first.id ?? 0, + // selectedOption: "${adVM.vehicleAdsDurations.first.days} Days", + // itemPrice: adVM.vehicleAdsDurations.first.price!.toInt().toString(), + // ), + // ); } Future updateUserImage(String image) async { diff --git a/lib/view_models/requests_view_model.dart b/lib/view_models/requests_view_model.dart index 6ef229d..c4b303e 100644 --- a/lib/view_models/requests_view_model.dart +++ b/lib/view_models/requests_view_model.dart @@ -69,7 +69,7 @@ class RequestsVM extends BaseVM { paramsForGetRequests = { "pageSize": 100, "pageIndex": 0, - "requestType": 0, + // "requestType": 0, }; if (appType == AppType.provider) { paramsForGetRequests.addEntries([MapEntry("providerID", AppState().getUser.data!.userInfo!.providerId)]); @@ -460,7 +460,7 @@ class RequestsVM extends BaseVM { comment: message, offerStatusText: "", )); - context.read().onNewMessageReceived(messages: [chatMessageModel], requestsVM: this, isMyOwnOffer: true); + context.read().onNewMessageReceivedForRequestOffer(messages: [chatMessageModel], requestsVM: this, isMyOwnOffer: true); if (!isFromChatScreen) { ChatViewArgumentsForRequest chatViewArgumentsForRequest = ChatViewArgumentsForRequest( diff --git a/lib/view_models/user_view_model.dart b/lib/view_models/user_view_model.dart index b488d3f..264cfb1 100644 --- a/lib/view_models/user_view_model.dart +++ b/lib/view_models/user_view_model.dart @@ -347,7 +347,12 @@ class UserVM extends BaseVM { //Utils.showLoading(context); LoginPasswordRespModel user = await userRepo.loginV2OTP(userToken, loginType!); if (user.messageStatus == 1) { - Response response2 = await userRepo.loginV2OTPVerify(user.data!.userToken ?? "", "9999"); + Response response2 = await userRepo.loginV2OTPVerify( + user.data!.userToken ?? "", + "9999", + AppState().getDeviceType ?? "1", + AppState().getDeviceToken ?? "", + ); RegisterUserRespModel verifiedUser = RegisterUserRespModel.fromJson(jsonDecode(response2.body)); if (verifiedUser.messageStatus == 1) { User user = User.fromJson(jsonDecode(response2.body)); @@ -387,13 +392,18 @@ class UserVM extends BaseVM { onClick: (String code) async { pop(context); Utils.showLoading(context); - Response response2 = await userRepo.loginV2OTPVerify(user.data!.userToken ?? "", code); + Response response2 = await userRepo.loginV2OTPVerify( + user.data!.userToken ?? "", + code, + AppState().getDeviceType ?? "1", + AppState().getDeviceToken ?? "", + ); Utils.hideLoading(context); RegisterUserRespModel verifiedUser = RegisterUserRespModel.fromJson(jsonDecode(response2.body)); if (verifiedUser.messageStatus == 1) { User user = User.fromJson(jsonDecode(response2.body)); if (appType == AppType.provider) { - if (user.data!.userInfo!.roleId == 5 || user.data!.userInfo!.roleId == 6 || user.data!.userInfo!.roleId == 7 ) { + if (user.data!.userInfo!.roleId == 5 || user.data!.userInfo!.roleId == 6 || user.data!.userInfo!.roleId == 7) { AppState().setUser = user; SharedPrefManager.setUserToken(user.data!.accessToken ?? ""); SharedPrefManager.setUserId(user.data!.userInfo!.userId ?? ""); @@ -455,7 +465,12 @@ class UserVM extends BaseVM { onClick: (String code) async { pop(context); Utils.showLoading(context); - Response response2 = await userRepo.loginV2OTPVerify(user.data!.userToken ?? "", code); + Response response2 = await userRepo.loginV2OTPVerify( + user.data!.userToken ?? "", + code, + AppState().getDeviceType ?? "1", + AppState().getDeviceToken ?? "", + ); Utils.hideLoading(context); RegisterUserRespModel verifiedUser = RegisterUserRespModel.fromJson(jsonDecode(response2.body)); if (verifiedUser.messageStatus == 1) { diff --git a/lib/views/advertisement/ad_duration_selection_sheet_content.dart b/lib/views/advertisement/ad_duration_selection_sheet_content.dart index e5c5106..2f41365 100644 --- a/lib/views/advertisement/ad_duration_selection_sheet_content.dart +++ b/lib/views/advertisement/ad_duration_selection_sheet_content.dart @@ -56,7 +56,7 @@ class AdDurationSelectionSheetContent extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ - ("${adDuration.days}" + LocaleKeys.daysVar.tr()) + ("${adDuration.days}${LocaleKeys.daysVar.tr()}") .toString() .toText(fontSize: 16, isBold: true), 4.height, @@ -101,7 +101,7 @@ class AdDurationSelectionSheetContent extends StatelessWidget { SelectionModel( selectedId: adDuration.id ?? 0, selectedOption: - ("${adDuration.days} " + LocaleKeys.daysVar.tr()), + ("${adDuration.days} ${LocaleKeys.daysVar.tr()}"), itemPrice: adDuration.price!.toInt().toString(), ), ); @@ -111,7 +111,7 @@ class AdDurationSelectionSheetContent extends StatelessWidget { SelectionModel( selectedId: adDuration.id ?? 0, selectedOption: - ("${adDuration.days} " + LocaleKeys.daysVar.tr()), + ("${adDuration.days} ${LocaleKeys.daysVar.tr()}"), itemPrice: adDuration.price!.toInt().toString(), ), ); diff --git a/lib/views/advertisement/ads_buyer_chats_list_view.dart b/lib/views/advertisement/ads_buyer_chats_list_view.dart new file mode 100644 index 0000000..339a745 --- /dev/null +++ b/lib/views/advertisement/ads_buyer_chats_list_view.dart @@ -0,0 +1,95 @@ +import 'package:flutter/material.dart'; +import 'package:mc_common_app/config/routes.dart'; +import 'package:mc_common_app/extensions/int_extensions.dart'; +import 'package:mc_common_app/extensions/string_extensions.dart'; +import 'package:mc_common_app/generated/locale_keys.g.dart'; +import 'package:mc_common_app/models/advertisment_models/ad_details_model.dart'; +import 'package:mc_common_app/models/chat_models/buyers_chat_for_ads_model.dart'; +import 'package:mc_common_app/theme/colors.dart'; +import 'package:mc_common_app/utils/enums.dart'; +import 'package:mc_common_app/utils/navigator.dart'; +import 'package:mc_common_app/view_models/ad_view_model.dart'; +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/extensions/extensions_widget.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:provider/provider.dart'; + +class AdsBuyerChatsListView extends StatelessWidget { + final List buyersListViewArguments; + + const AdsBuyerChatsListView({super.key, required this.buyersListViewArguments}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: CustomAppBar(title: LocaleKeys.chat.tr()), + body: buyersListViewArguments.isEmpty + ? Center(child: LocaleKeys.noOffersShow.tr().toText(fontSize: 16, color: MyColors.lightTextColor)) + : ListView.separated( + itemCount: buyersListViewArguments.length, + padding: const EdgeInsets.all(16), + itemBuilder: (context, index) { + BuyersChatForAdsModel chatForAdsModel = buyersListViewArguments[index]; + return Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + (chatForAdsModel.buyerName ?? "").toText(fontSize: 16, isBold: true), + if (chatForAdsModel.unReadMessagesCount != null && chatForAdsModel.unReadMessagesCount! > 0) ...[ + Center( + child: "${chatForAdsModel.unReadMessagesCount ?? "1"}".toText( + color: Colors.white, + isBold: true, + fontSize: 10, + ), + ).toContainer( + backgroundColor: MyColors.redColor, + borderRadius: 100, + paddingAll: 1, + width: 22, + height: 22, + ), + ] + ], + ), + 8.height, + Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + (chatForAdsModel.lastMessage ?? "").toText(color: MyColors.lightTextColor, fontSize: 12), + ], + ), + + if (chatForAdsModel.lastMessageDateTime != null) ...[ + DateTime.parse(chatForAdsModel.lastMessageDateTime!).getTimeAgo().toText(color: MyColors.lightTextColor), + ], + // const Icon( + // Icons.arrow_forward, + // color: MyColors.darkIconColor, + // size: 18, + // ), + ], + ), + ], + ).onPress(() async { + ChatViewArgumentsForAd chatViewArgumentsForAd = ChatViewArgumentsForAd(receiverUserID: chatForAdsModel.buyerUserID, adsID: chatForAdsModel.adsID); + + ChatViewArguments chatViewArguments = ChatViewArguments(chatTypeEnum: ChatTypeEnum.ads, chatViewArgumentsForAd: chatViewArgumentsForAd); + + final chatVM = context.read(); + await chatVM.getUsersChatMessagesForAd(context: context, isForBuyer: false, adsChatBuyerId: chatForAdsModel.id).whenComplete( + () => navigateWithName(context, AppRoutes.chatView, arguments: chatViewArguments), + ); + }).toContainer(isShadowEnabled: true); + }, + separatorBuilder: (context, index) => 16.height, + ), + ); + } +} diff --git a/lib/views/advertisement/ads_detail_view.dart b/lib/views/advertisement/ads_detail_view.dart index 8999417..93a7a73 100644 --- a/lib/views/advertisement/ads_detail_view.dart +++ b/lib/views/advertisement/ads_detail_view.dart @@ -5,9 +5,7 @@ import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; import 'package:mc_common_app/generated/locale_keys.g.dart'; -import 'package:mc_common_app/main.dart'; import 'package:mc_common_app/models/advertisment_models/ad_details_model.dart'; -import 'package:mc_common_app/models/advertisment_models/ads_bank_details_model.dart'; import 'package:mc_common_app/models/advertisment_models/special_service_model.dart'; import 'package:mc_common_app/models/general_models/widgets_models.dart'; import 'package:mc_common_app/theme/colors.dart'; diff --git a/lib/views/advertisement/ads_filter_view.dart b/lib/views/advertisement/ads_filter_view.dart index e9900d1..1c3ae8a 100644 --- a/lib/views/advertisement/ads_filter_view.dart +++ b/lib/views/advertisement/ads_filter_view.dart @@ -1,3 +1,6 @@ +import 'dart:async'; +import 'dart:developer'; + import 'package:flutter/material.dart'; import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; @@ -5,6 +8,7 @@ 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/theme/colors.dart'; +import 'package:mc_common_app/utils/enums.dart'; import 'package:mc_common_app/view_models/ad_view_model.dart'; import 'package:mc_common_app/widgets/button/show_fill_button.dart'; import 'package:mc_common_app/widgets/common_widgets/app_bar.dart'; @@ -14,9 +18,31 @@ import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:provider/provider.dart'; import 'package:easy_localization/easy_localization.dart'; -class AdsFilterView extends StatelessWidget { +class AdsFilterView extends StatefulWidget { const AdsFilterView({super.key}); + @override + State createState() => _AdsFilterViewState(); +} + +class _AdsFilterViewState extends State { + late AdVM adVM; + + @override + void initState() { + adVM = context.read(); + scheduleMicrotask(() async { + await adVM.populateDataForAdFilter(); + }); + super.initState(); + } + + @override + void dispose() { + adVM.clearAdFilterSelections(); + super.dispose(); + } + @override Widget build(BuildContext context) { return Scaffold( @@ -32,9 +58,14 @@ class AdsFilterView extends StatelessWidget { ), body: Consumer( builder: (BuildContext context, AdVM adVM, Widget? child) { + if (adVM.state == ViewState.busy) { + return const Center( + child: CircularProgressIndicator(), + ); + } return WillPopScope( onWillPop: () async { - context.read().resetValues(); + adVM.clearAdFilterSelections(); return true; }, child: Column( @@ -107,7 +138,7 @@ class AdsFilterView extends StatelessWidget { actionWidget: Builder(builder: (context) { List vehicleOwnerDrop = []; for (var element in adVM.exploreAdsEnums) { - vehicleOwnerDrop.add(DropValue(element.id.toInt(), "${element.enumValueStr} Ads", "")); + vehicleOwnerDrop.add(DropValue(element.enumValue.toInt(), "${element.enumValueStr} Ads", "")); } return DropdownField( (DropValue value) => adVM.updateSelectionVehicleAdOwnerId(SelectionModel(selectedId: value.id, selectedOption: value.value), isForSearch: true), @@ -135,6 +166,7 @@ class AdsFilterView extends StatelessWidget { maxHeight: 55, title: LocaleKeys.search.tr(), onPressed: () { + Navigator.pop(context); adVM.getAdsBasedOnFilters(); }, backgroundColor: MyColors.darkPrimaryColor, @@ -148,10 +180,10 @@ class AdsFilterView extends StatelessWidget { InkWell( onTap: () => adVM.clearAdsFilters(), child: LocaleKeys.clearFilters.tr().toText( - fontSize: 14, - isBold: true, - color: MyColors.darkPrimaryColor, - ), + fontSize: 14, + isBold: true, + color: MyColors.darkPrimaryColor, + ), ), 10.height, ], diff --git a/lib/views/appointments/widgets/customer_appointment_slider_widget.dart b/lib/views/appointments/widgets/common_appointment_slider_widget.dart similarity index 91% rename from lib/views/appointments/widgets/customer_appointment_slider_widget.dart rename to lib/views/appointments/widgets/common_appointment_slider_widget.dart index 4374a5a..df71f61 100644 --- a/lib/views/appointments/widgets/customer_appointment_slider_widget.dart +++ b/lib/views/appointments/widgets/common_appointment_slider_widget.dart @@ -1,4 +1,5 @@ import 'package:carousel_slider/carousel_slider.dart'; +import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:mc_common_app/classes/app_state.dart'; @@ -6,6 +7,7 @@ import 'package:mc_common_app/classes/consts.dart'; import 'package:mc_common_app/config/routes.dart'; import 'package:mc_common_app/extensions/int_extensions.dart'; import 'package:mc_common_app/extensions/string_extensions.dart'; +import 'package:mc_common_app/generated/locale_keys.g.dart'; import 'package:mc_common_app/models/appointments_models/appointment_list_model.dart'; import 'package:mc_common_app/theme/colors.dart'; import 'package:mc_common_app/utils/enums.dart'; @@ -16,12 +18,12 @@ import 'package:mc_common_app/views/advertisement/custom_add_button.dart'; import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; import 'package:provider/provider.dart'; -class CustomerAppointmentSliderWidget extends StatelessWidget { - Function(AppointmentListModel)? onAppointmentClick; +class CommonAppointmentSliderWidget extends StatelessWidget { + final Function(AppointmentListModel)? onAppointmentClick; - CustomerAppointmentSliderWidget({Key? key, this.onAppointmentClick}) : super(key: key); + const CommonAppointmentSliderWidget({Key? key, this.onAppointmentClick}) : super(key: key); - Widget getCorouselWidget(AppType appType, AppointmentsVM appointmentsVM) { + Widget getCarouselSliderWidget(AppType appType, AppointmentsVM appointmentsVM) { return CarouselSlider.builder( options: CarouselOptions( height: appType == AppType.provider ? 110 : 140, @@ -52,9 +54,9 @@ class CustomerAppointmentSliderWidget extends StatelessWidget { } else { if (AppState().currentAppType == AppType.provider) { if (model.myUpComingAppointments.isEmpty) { - return "No Upcoming Appointment Available".toText().paddingAll(21); + return LocaleKeys.noUpcomingAppointments.tr().toText(fontSize: 16, color: MyColors.lightTextColor).paddingAll(21); } else { - return getCorouselWidget(AppState().currentAppType, model); + return getCarouselSliderWidget(AppState().currentAppType, model); } } else { if (model.myUpComingAppointments.isEmpty) { @@ -62,16 +64,16 @@ class CustomerAppointmentSliderWidget extends StatelessWidget { needsBorder: true, bgColor: MyColors.white, onTap: () => context.read().onNavbarTapped(0), - text: "Add New Appointment", + text: LocaleKeys.addNewAppointment.tr(), icon: Container( height: 24, width: 24, decoration: const BoxDecoration(shape: BoxShape.circle, color: MyColors.darkTextColor), child: const Icon(Icons.add, color: MyColors.white), ), - ).padding(EdgeInsets.symmetric(vertical: 10, horizontal: 21)); + ).padding(const EdgeInsets.symmetric(vertical: 10, horizontal: 21)); } else { - return getCorouselWidget(AppState().currentAppType, model); + return getCarouselSliderWidget(AppState().currentAppType, model); } } } @@ -164,7 +166,7 @@ class BuildAppointmentContainerForCustomer extends StatelessWidget { List buildServicesFromAppointment({required AppointmentListModel appointmentListModel}) { if (appointmentListModel.appointmentServicesList == null || appointmentListModel.appointmentServicesList!.isEmpty) { - return [SizedBox()]; + return [const SizedBox()]; } if (appointmentListModel.appointmentServicesList!.length == 1) { diff --git a/lib/views/appointments/widgets/custom_calender_widget.dart b/lib/views/appointments/widgets/custom_calender_widget.dart index fa903d7..8eb3435 100644 --- a/lib/views/appointments/widgets/custom_calender_widget.dart +++ b/lib/views/appointments/widgets/custom_calender_widget.dart @@ -107,15 +107,15 @@ class _CustomCalenderAppointmentWidgetState extends State { chatMessageType: ChatMessageTypeEnum.freeText, ); } else if (chatTypeEnum == ChatTypeEnum.ads) { + status = await chatVM.onTextMessageSendForAds( + receiverId: chatViewArgumentsForAd!.receiverUserID ?? "", + chatMessageType: ChatMessageTypeEnum.freeText, + message: chatVM.chatMessageText, + adId: chatViewArgumentsForAd!.adsID!, + context: context, + ); + } else if (chatTypeEnum == ChatTypeEnum.general) { } else {} return status; } @@ -150,7 +158,7 @@ class _ChatViewState extends State { body: Consumer2(builder: (BuildContext context, ChatVM chatVM, RequestsVM requestVM, Widget? child) { List chatMessages = []; if (chatTypeEnum == ChatTypeEnum.ads) { - chatMessages = chatViewArgumentsForAd!.adDetailsModel!.adMessages ?? []; + chatMessages = chatVM.currentMessagesForAds; } else if (chatTypeEnum == ChatTypeEnum.requestOffer) { if (AppState().currentAppType == AppType.customer) { chatMessages = chatVM.serviceProviderOffersList[chatViewArgumentsForRequest!.providerIndex].chatMessages ?? []; @@ -218,15 +226,7 @@ class _ChatViewState extends State { size: 30, ).onPress( () async { - final status = await chatVM.onTextMessageSendForRequest( - context: context, - receiverId: chatViewArgumentsForRequest!.receiverId, - message: chatVM.chatMessageText, - requestId: chatViewArgumentsForRequest!.requestId ?? 0, - offerPrice: "0.0", - chatMessageType: ChatMessageTypeEnum.freeText, - ); - + final status = await onTextMessageSend(); if (status) { chatVM.scrollChatDown(); chatVM.clearChatMessageText(); diff --git a/lib/views/common_fragments/ads_fragment.dart b/lib/views/common_fragments/ads_fragment.dart new file mode 100644 index 0000000..c2131da --- /dev/null +++ b/lib/views/common_fragments/ads_fragment.dart @@ -0,0 +1,146 @@ +import 'package:flutter/material.dart'; +import 'package:mc_common_app/classes/app_state.dart'; +import 'package:mc_common_app/classes/consts.dart'; +import 'package:mc_common_app/config/dependency_injection.dart'; +import 'package:mc_common_app/config/routes.dart'; +import 'package:mc_common_app/extensions/int_extensions.dart'; +import 'package:mc_common_app/extensions/string_extensions.dart'; +import 'package:mc_common_app/generated/locale_keys.g.dart'; +import 'package:mc_common_app/models/advertisment_models/ad_details_model.dart'; +import 'package:mc_common_app/theme/colors.dart'; +import 'package:mc_common_app/utils/enums.dart'; +import 'package:mc_common_app/utils/navigator.dart'; +import 'package:mc_common_app/view_models/ad_view_model.dart'; +import 'package:mc_common_app/views/advertisement/ads_list.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/categories_list.dart'; +import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; +import 'package:provider/provider.dart'; +import 'package:easy_localization/easy_localization.dart'; + +class AdsFragment extends StatelessWidget { + const AdsFragment({Key? key}) : super(key: key); + + List getAdsList(AdVM adVM) { + if (adVM.isExploreAdsTapped) { + return adVM.exploreAdsFilteredList; + } + if (adVM.myAdsFilteredList.isNotEmpty) { + return adVM.myAdsFilteredList; + } + return []; + } + + @override + Widget build(BuildContext context) { + return Consumer( + builder: (BuildContext context, AdVM adVM, Widget? child) { + return Scaffold( + appBar: CustomAppBar( + title: LocaleKeys.ads.tr(), + isRemoveBackButton: true, + actions: [ + Padding( + padding: EdgeInsets.only(top: adVM.adsFiltersCounter > 0 ? 20 : 0, right: 21), + child: Badge( + isLabelVisible: adVM.adsFiltersCounter > 0, + largeSize: 15, + smallSize: 20, + backgroundColor: MyColors.darkPrimaryColor, + label: Text('${adVM.adsFiltersCounter}'), + child: MyAssets.searchIcon.buildSvg(), + ), + ).onPress(() { + navigateWithName(context, AppRoutes.adsFilterView); + }) + ], + ), + body: SizedBox( + width: double.infinity, + height: double.infinity, + child: Column( + children: [ + 16.height, + Consumer( + builder: (BuildContext context, AdVM adVM, Widget? child) { + return Column( + children: [ + Row( + children: [ + Expanded( + child: ShowFillButton( + isFilled: adVM.isExploreAdsTapped, + maxHeight: 55, + title: LocaleKeys.exploreAds.tr(), + txtColor: adVM.isExploreAdsTapped ? MyColors.white : MyColors.darkTextColor, + onPressed: () { + print("accessToken: ${AppState().getUser.data!.accessToken}"); + adVM.populateAdsFilterList(); + if (adVM.myAds.isEmpty) { + adVM.getMyAds(); + } + adVM.updateIsExploreAds(true); + }, + ), + ), + 12.width, + Expanded( + child: ShowFillButton( + isFilled: !adVM.isExploreAdsTapped, + txtColor: !adVM.isExploreAdsTapped ? MyColors.white : MyColors.darkTextColor, + maxHeight: 55, + title: LocaleKeys.myAds.tr(), + onPressed: () { + adVM.updateIsExploreAds(false); + }, + ), + ), + ], + ).horPaddingMain(), + if (adVM.isExploreAdsTapped) ...[ + if (adVM.adsFiltersCounter == 0) ...[ + 16.height, + FiltersList( + filterList: adVM.exploreAdsFilterOptions, + onFilterTapped: (index, selectedFilterId) => adVM.applyFilterOnExploreAds(createdByRoleFilter: selectedFilterId.toCreatedByRoleEnum()), + needLeftPadding: false) + .paddingOnly(left: 21), + ] + ] else ...[ + 16.height, + FiltersList( + filterList: adVM.myAdsFilterOptions, + onFilterTapped: (index, selectedFilterId) => adVM.applyFilterOnMyAds(adPostStatusEnum: selectedFilterId.toAdPostEnum()), + needLeftPadding: false, + ).paddingOnly(left: 21), + ], + ], + ); + }, + ), + 16.height, + Expanded( + child: RefreshIndicator( + onRefresh: () async { + await adVM.getExploreAds(); + await adVM.getMyAds(); + }, + child: BuildAdsList(isAdsFragment: true, shouldShowAdStatus: !adVM.isExploreAdsTapped, adsList: getAdsList(adVM)), + ), + ) + ], + ), + ), + floatingActionButton: FloatingActionButton( + onPressed: () async { + navigateWithName(context, AppRoutes.selectAdTypeView, arguments: injector.get().currentAppType == AppType.provider); + }, + backgroundColor: MyColors.darkPrimaryColor, + child: const Icon(Icons.add, color: MyColors.white), + ), + ); + }, + ); + } +} diff --git a/lib/views/common_fragments/my_requests_fragment.dart b/lib/views/common_fragments/my_requests_fragment.dart new file mode 100644 index 0000000..8dee432 --- /dev/null +++ b/lib/views/common_fragments/my_requests_fragment.dart @@ -0,0 +1,81 @@ +import 'package:mc_common_app/classes/app_state.dart'; +import 'package:mc_common_app/config/routes.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/requests_view_model.dart'; +import 'package:flutter/material.dart'; +import 'package:mc_common_app/extensions/int_extensions.dart'; +import 'package:mc_common_app/extensions/string_extensions.dart'; +import 'package:mc_common_app/theme/colors.dart'; +import 'package:mc_common_app/utils/enums.dart'; +import 'package:mc_common_app/views/requests/widget/request_item.dart'; +import 'package:mc_common_app/widgets/common_widgets/app_bar.dart'; +import 'package:mc_common_app/widgets/common_widgets/categories_list.dart'; +import 'package:provider/provider.dart'; +import 'package:easy_localization/easy_localization.dart'; + +class MyRequestsFragment extends StatelessWidget { + const MyRequestsFragment({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: CustomAppBar( + title: LocaleKeys.myRequests.tr(), + isRemoveBackButton: true, + ), + body: Container( + color: MyColors.backgroundColor, + width: double.infinity, + height: double.infinity, + child: Consumer(builder: (BuildContext context, RequestsVM requestsVM, Widget? child) { + return Column( + children: [ + 16.height, + FiltersList( + filterList: requestsVM.requestsTypeFilterOptions, + onFilterTapped: (index, selectedFilterId) { + requestsVM.applyFilterOnRequestsVM(requestsTypeEnum: selectedFilterId.toRequestTypeStatusEnum()); + }, + ), + 8.height, + Expanded( + child: RefreshIndicator( + onRefresh: () async => await requestsVM.getRequests(isNeedToRebuild: true, appType: AppType.provider), + child: requestsVM.state == ViewState.busy + ? const Center(child: CircularProgressIndicator()) + : requestsVM.myFilteredRequests.isEmpty + ? Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + LocaleKeys.noRequeststoShow.tr().toText(fontSize: 16, color: MyColors.lightTextColor), + ], + ) + : ListView.separated( + itemBuilder: (context, index) { + return RequestItem(request: requestsVM.myFilteredRequests[index], appType: AppType.provider, requestIndex: index); + }, + separatorBuilder: (context, index) { + return 16.height; + }, + itemCount: requestsVM.myFilteredRequests.length, + padding: const EdgeInsets.only(left: 16, right: 16, bottom: 16, top: 8), + ), + )) + ], + ); + }), + ), + floatingActionButton: AppState().currentAppType == AppType.customer + ? FloatingActionButton( + onPressed: () => navigateWithName(context, AppRoutes.createRequestPage), + backgroundColor: MyColors.darkPrimaryColor, + child: const Icon( + Icons.add, + color: MyColors.white, + ), + ) + : null, + ); + } +} diff --git a/lib/views/requests/widget/request_item.dart b/lib/views/requests/widget/request_item.dart index 1c0bb96..1d6fa66 100644 --- a/lib/views/requests/widget/request_item.dart +++ b/lib/views/requests/widget/request_item.dart @@ -49,7 +49,7 @@ class RequestItem extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.end, children: [ - if (request.offerCount > 0) ...[ + if (request.offerCount > 0 && appType == AppType.customer) ...[ Center( child: "${request.offerCount}".toText( color: Colors.white, diff --git a/lib/widgets/common_widgets/my_service_provider.dart b/lib/widgets/common_widgets/my_service_provider.dart deleted file mode 100644 index f316c1b..0000000 --- a/lib/widgets/common_widgets/my_service_provider.dart +++ /dev/null @@ -1,47 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:mc_common_app/classes/consts.dart'; -import 'package:mc_common_app/config/routes.dart'; -import 'package:mc_common_app/extensions/int_extensions.dart'; -import 'package:mc_common_app/extensions/string_extensions.dart'; -import 'package:mc_common_app/models/provider_branches_models/branch_detail_model.dart'; -import 'package:mc_common_app/utils/navigator.dart'; -import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; - -class ServiceProviderWidget extends StatelessWidget { - final List nearbyBranches; - - const ServiceProviderWidget({Key? key, required this.nearbyBranches}) : super(key: key); - - @override - Widget build(BuildContext context) { - return SizedBox( - width: double.infinity, - height: 140, - child: ListView.builder( - itemCount: nearbyBranches.length, - scrollDirection: Axis.horizontal, - shrinkWrap: true, - itemBuilder: (BuildContext context, int index) { - BranchDetailModel branchDetailModel = nearbyBranches[index]; - return SizedBox( - width: 90, - child: Column( - children: [ - Image.asset( - MyAssets.bnCar, - width: 80, - height: 80, - fit: BoxFit.cover, - ).toCircle(borderRadius: 100), - 8.height, - "${branchDetailModel.branchName}".toText(fontSize: 14, isBold: true, textAlign: TextAlign.center), - ], - ), - ).onPress(() { - navigateWithName(context, AppRoutes.branchDetailPage, arguments: branchDetailModel); - }); - }, - ), - ); - } -} diff --git a/lib/widgets/common_widgets/provider_appointment_slider_widget.dart b/lib/widgets/common_widgets/provider_appointment_slider_widget.dart deleted file mode 100644 index 98b93e1..0000000 --- a/lib/widgets/common_widgets/provider_appointment_slider_widget.dart +++ /dev/null @@ -1,119 +0,0 @@ -import 'package:carousel_slider/carousel_slider.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:mc_common_app/classes/consts.dart'; -import 'package:mc_common_app/extensions/int_extensions.dart'; -import 'package:mc_common_app/extensions/string_extensions.dart'; -import 'package:mc_common_app/theme/colors.dart'; -import 'package:mc_common_app/widgets/extensions/extensions_widget.dart'; - -class ProviderAppointmentSliderWidget extends StatelessWidget { - const ProviderAppointmentSliderWidget({Key? key}) : super(key: key); - - - @override - Widget build(BuildContext context) { - return CarouselSlider.builder( - options: CarouselOptions( - height: 160, - viewportFraction: 1.0, - enlargeCenterPage: false, - enableInfiniteScroll: false, - // - // onPageChanged: (index) { - // setState(() { - // _current = index; - // }); - // }, - ), - itemCount: 10, - itemBuilder: (BuildContext context, int itemIndex, int pageViewIndex) => const BuildAppointmentContainerForProvider(), - ); - } - - -} - -class BuildAppointmentContainerForProvider extends StatelessWidget { - const BuildAppointmentContainerForProvider({Key? key}) : super(key: key); - - Widget showServices(String title, String icon) { - return Row( - children: [ - SvgPicture.asset(icon), - 8.width, - title.toText( - fontSize: 14, - isBold: true, - ), - ], - ); - } - - @override - Widget build(BuildContext context) { - return Container( - margin: const EdgeInsets.only(bottom: 21, left: 21, right: 21, top: 7), - child: Column( - children: [ - Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - "Olaya Brach".toText( - color: MyColors.lightTextColor, - isBold: true, - ), - "Abdullah Alhbas".toText( - isBold: true, - fontSize: 14, - ), - Row( - children: [ - "Appt. On:".toText( - color: MyColors.lightTextColor, - ), - 2.width, - "19-Mar-2023 11:48 AM".toText(), - ], - ), - ], - ), - ), - "1+ Requests".toText(fontSize: 10).toContainer( - borderRadius: 15, - backgroundColor: MyColors.lightGreyEAColor, - padding: const EdgeInsets.symmetric( - vertical: 6, - horizontal: 12, - ), - ), - ], - ), - 8.height, - Row( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Expanded( - child: Column( - children: [ - showServices("Maintenance", MyAssets.maintenanceIcon ), - 2.height, - showServices("Accessories and Modification", MyAssets.modificationsIcon,), - ], - ), - ), - const Icon( - Icons.arrow_forward, - ), - ], - ), - ], - ).toWhiteContainer(width: double.infinity, allPading: 12), - ); - } -} -