diff --git a/lib/controller/home/map_passenger_controller.dart b/lib/controller/home/map_passenger_controller.dart index 0000b07..1d23eea 100644 --- a/lib/controller/home/map_passenger_controller.dart +++ b/lib/controller/home/map_passenger_controller.dart @@ -575,7 +575,7 @@ class MapPassengerController extends GetxController { void getDrawerMenu() { heightMenuBool = !heightMenuBool; widthMapTypeAndTraffic = heightMenuBool == true ? 0 : 50; - heightMenu = heightMenuBool == true ? 70 : 0; + heightMenu = heightMenuBool == true ? 80 : 0; widthMenu = heightMenuBool == true ? 110 : 0; update(); } @@ -3160,7 +3160,7 @@ class MapPassengerController extends GetxController { } else { isMainBottomMenuMap = !isMainBottomMenuMap; mainBottomMenuMapHeight = - isMainBottomMenuMap == true ? Get.height * .2 : Get.height * .55; + isMainBottomMenuMap == true ? Get.height * .2 : Get.height * .7; isWayPointSheet = false; if (heightMenuBool == true) { getDrawerMenu(); @@ -4074,7 +4074,7 @@ class MapPassengerController extends GetxController { LatLngBounds(northeast: northeast, southwest: southwest); // Fit the camera to the bounds - var cameraUpdate = CameraUpdate.newLatLngBounds(boundsData, 100); + var cameraUpdate = CameraUpdate.newLatLngBounds(boundsData, 130); mapController!.animateCamera(cameraUpdate); // getDistanceFromText(data[0]['distance']['text']); @@ -4132,117 +4132,51 @@ class MapPassengerController extends GetxController { } Future _animatePolyline(List coordinates) async { - // Initial animation - polyLines.clear(); - List animatedPoints = []; + const int totalAnimations = 7; - // Draw initial polyline - for (int i = 0; i < coordinates.length; i++) { - animatedPoints.add(coordinates[i]); - polyLines.clear(); - polyLines.add( - Polyline( - polylineId: const PolylineId('animated_route'), - points: List.from(animatedPoints), - width: 4, - color: AppColor.primaryColor, - endCap: Cap.roundCap, - startCap: Cap.roundCap, - geodesic: true, - ), - ); - - update(); - await Future.delayed(const Duration(milliseconds: 1)); + Color getAnimationColor(int cycle) { + switch (cycle) { + case 0: + return AppColor.primaryColor; + case 1: + return AppColor.writeColor; + case 2: + return AppColor.primaryColor; + default: + return AppColor.primaryColor; + } } - // Color change animations - for (int cycle = 0; cycle < 6; cycle++) { - // Change to green + for (int cycle = 0; cycle < totalAnimations; cycle++) { polyLines.clear(); - polyLines.add( - Polyline( - polylineId: const PolylineId('animated_route'), - points: coordinates, - width: 4, - color: AppColor.bronze, - endCap: Cap.roundCap, - startCap: Cap.roundCap, - geodesic: true, - ), - ); - update(); - await Future.delayed(const Duration(milliseconds: 500)); + List animatedPoints = []; - // Change back to primary color - polyLines.clear(); - polyLines.add( - Polyline( - polylineId: const PolylineId('animated_route'), - points: coordinates, - width: 4, - color: AppColor.writeColor, - endCap: Cap.roundCap, - startCap: Cap.roundCap, - geodesic: true, - ), - ); - update(); - await Future.delayed(const Duration(milliseconds: 500)); + for (int i = 0; i < coordinates.length; i++) { + animatedPoints.add(coordinates[i]); + polyLines.clear(); + polyLines.add( + Polyline( + polylineId: const PolylineId('animated_route'), + points: List.from(animatedPoints), + width: 4, + color: getAnimationColor(cycle), + endCap: Cap.roundCap, + startCap: Cap.roundCap, + geodesic: true, + ), + ); + update(); + await Future.delayed(const Duration(milliseconds: 10)); + } + + if (cycle < totalAnimations - 1) { + await Future.delayed(const Duration(milliseconds: 500)); + polyLines.clear(); + update(); + await Future.delayed(const Duration(milliseconds: 200)); + } } } -// Add this method to your controller class - // Future _animatePolyline(List coordinates) async { - // // Clear existing polylines - // polyLines.clear(); - - // // Create segments for animation - // List animatedPoints = []; - - // // Calculate step size for smoother animation - // int stepSize = (coordinates.length / 20).round(); - // stepSize = stepSize < 1 ? 1 : stepSize; - - // for (int i = 0; i < coordinates.length; i += stepSize) { - // // Add points gradually - // animatedPoints.add(coordinates[i]); - - // if (animatedPoints.length > 1) { - // // Remove previous polyline - // if (polyLines.isNotEmpty) { - // polyLines.clear(); - // } - // // Add new polyline segment - // polyLines.add( - // Polyline( - // polylineId: const PolylineId('animated_route'), - // points: List.from(animatedPoints), - // width: 4, - // color: Colors.blue, - // ), - // ); - - // // Update camera position to follow animation - // if (mapController != null) { - // final bounds = LatLngBounds( - // southwest: animatedPoints.reduce((value, element) => LatLng( - // min(value.latitude, element.latitude), - // min(value.longitude, element.longitude))), - // northeast: animatedPoints.reduce((value, element) => LatLng( - // max(value.latitude, element.latitude), - // max(value.longitude, element.longitude))), - // ); - - // mapController!.animateCamera( - // CameraUpdate.newLatLngBounds(bounds, 100), - // ); - // } - // } - - // update(); - // await Future.delayed(const Duration(milliseconds: 50)); - // } - // } String shortenAddress(String fullAddress) { // Split the address into parts diff --git a/lib/controller/local/translations.dart b/lib/controller/local/translations.dart index 2043160..d4a1bb4 100644 --- a/lib/controller/local/translations.dart +++ b/lib/controller/local/translations.dart @@ -4,245 +4,290 @@ class MyTranslation extends Translations { @override Map> get keys => { "ar": { - "You should restart app to change language": - "يجب إعادة تشغيل التطبيق لتغيير اللغة", - "Home Page": "الصفحة الرئيسية", - "To change Language the App": "لتغيير لغة التطبيق", - "Learn more about our app and mission": - "تعرف على المزيد حول تطبيقنا ورسالتنا", - "Promos For Today": "عروض اليوم", - 'Choose your ride': "اختر رحلتك", - "Your Journey Begins Here": "رحلتك تبدأ هنا", - 'Bonus gift': 'بونص', "Pay": "ادفع", - "Get": "احصل على", - "Send to Driver Again": "إرسال إلى السائق مرة أخرى", - "Driver Name:": "اسم السائق:", - 'No trip data available': "لا توجد بيانات رحلة متاحة", - "Car Plate:": "رقم اللوحة:", "remaining": "متبقي", - "Order Cancelled": "تم إلغاء الطلب", - 'You canceled VIP trip': "ألغيت الرحلة", - "Passenger cancelled order": "الراكب قام بإلغاء الطلب", - "Your trip is scheduled": "رحلتك مجدولة", - "Don't forget your ride!": "لا تنسَ رحلتك!", - "Trip updated successfully": "تم تحديث الرحلة بنجاح", - "Car Make:": "ماركة السيارة:", - "Car Model:": "طراز السيارة:", "Car Color:": "لون السيارة:", - "Driver Phone:": "رقم هاتف السائق:", - 'Pre-booking': 'احجز مسبقًا', "Waiting VIP": "انتظار VIP", - "Driver List": "قائمة السائقين", "Confirm Trip": "تأكيد الرحلة", - "Select date and time of trip": "حدد تاريخ ووقت الرحلة", - "Date and Time Picker": "اختيار التاريخ والوقت", - "Trip Status:": "حالة الرحلة:", "pending": "قيد الانتظار", - "accepted": "تم القبول", - "rejected": "تم الرفض", - "Scheduled Time:": "الوقت المحدد:", - "No drivers available": "لا يوجد سائقين متاحين", - "Please try again in a few moments": - "يرجى المحاولة مرة أخرى بعد قليل", - "Unknown Driver": "سائق غير معروف", - "rides": "الرحلات", - "The reason is": "السبب هو", - "User does not have a wallet #1652": "المستخدم ليس لديه محفظة ", - "Price of trip": "سعر الرحلة", - "For Speed and Delivery trips, the price is calculated dynamically. For Comfort trips, the price is based on time and distance": - "بالنسبة لرحلات السرعة والتوصيل، يتم حساب السعر ديناميكياً. بالنسبة لرحلات الراحة، يتم حساب السعر بناءً على الوقت والمسافة", - "Phone Wallet Saved Successfully": "تم حفظ المحفظة الهاتفية بنجاح", - "Add wallet phone you use": "أضف محفظة الهاتف التي تستخدمها", - "Update Available": "تحديث متوفر", - 'Phone number must be exactly 11 digits long': - "رقم الهاتف يجب أن يكون بطول 11 رقماً", - 'Insert Wallet phone number': 'أدخل رقم هاتف المحفظة', - "Phone number isn't an Egyptian phone number": - "رقم الهاتف ليس رقم هاتف مصري", - "A new version of the app is available. Please update to the latest version.": - "تتوفر نسخة جديدة من التطبيق. يرجى التحديث إلى أحدث إصدار.", - "We use location to get accurate and nearest passengers for you": - "نستخدم الموقع للحصول على أقرب الركاب وأكثرهم دقة لك", - "This ride is already applied by another driver.": - "هذه الرحلة قام بقبولها سائق آخر بالفعل.", - "We use your precise location to find the nearest available driver and provide accurate pickup and dropoff information. You can manage this in Settings.": - "نستخدم موقعك الدقيق للعثور على أقرب سائق متاح وتوفير معلومات دقيقة عن مكان الاستلام والوجهة. يمكنك إدارة ذلك في الإعدادات.", - 'message From Driver': '‏رسالة من السائق', - 'message From passenger': "رسالة من الراكب", - "Where are you, sir?": "أنا وصلت حضرتك فين.", - "I've been trying to reach you but your phone is off.": - "بحاول أكلمك التلفون مغلق.", - "Please don't be late": "أرجو عدم التأخير", - "Please don't be late, I'm waiting for you at the specified location.": - "أرجو عدم التأخير، أنا منتظرك على ال لوكيشن المحدد.", - "My location is correct. You can search for me using the navigation app": - "موقعي صحيح. يمكنك البحث عني باستخدام تطبيق الملاحة", - "Hello, I'm at the agreed-upon location": - "مرحباً، أنا في المكان المتفق عليه", - "message From Driver": "رسالة من السائق", - - "How much longer will you be?": "‏قدامك قد إيه", - 'Phone number is verified before': "تم التحقق من رقم الهاتف مسبقاً", - 'Change Ride': 'تغيير الرحلة', - 'You can change the destination by long-pressing any point on the map': - 'يمكنك تغيير الوجهة بالضغط مطولاً على أي نقطة على الخريطة', - + "Where to": "على فين؟", + "Where are you going?": "رايح فين؟", + "Quick Actions": "إجراءات سريعة", + "My Wallet": "محفظتي", + "Order History": "سجل الطلبات", + "Contact Us": "اتصل بنا", + "Driver": "السائق", + "Complaint": "شكوى", + "Promos": "العروض", + "Recent Places": "الأماكن الأخيرة", + "From": "من", "WhatsApp Location Extractor": "مستخرج موقع واتساب", "Location Link": "رابط الموقع", "Paste location link here": "الصق رابط الموقع هنا", "Go to this location": "انتقل إلى هذا الموقع", - "Paste WhatsApp location link here": "الصق رابط موقع واتساب هنا", - "Pick from map destination": "حدد وجهتك على الخريطة", - "Pick or Tap to confirm": "حدد أو انقر للتأكيد", - "Select Order Type": "حدد نوع الطلب", - 'Accepted your order': "تم قبول طلبك", - "Choose who this order is for": "اختر لمن هذا الطلب", - "Order Accepted": "تم قبول الطلب", "with type": "مع النوع", - "accepted your order at price": "قبل طلبك بالسعر", - "I want to order for myself": "أريد أن أطلب لنفسي", - "I want to order for someone else": "أريد أن أطلب لشخص آخر", - "Cancel Trip from driver": "إلغاء الرحلة من السائق", + "Paste WhatsApp location link": "الصق رابط موقع واتساب", + "Select Order Type": "اختر نوع الطلب", + "Choose who this order is for": "اختر الطلب ده لمين؟", + "I want to order for myself": "أطلب لنفسي", + "I want to order for someone else": "أطلب لحد تاني", + "Cancel": "إلغاء", + "Order for someone else": "اطلب لشخص آخر", + "Order for myself": "اطلب لنفسي", + "Are you want to go this site": "عايز تروح المكان ده؟", + "Yes": "أيوة", + "No": "لأ", + "Are you sure to delete this location?": + "متأكد إنك عايز تحذف الموقع ده؟", + "deleted": "تم الحذف", + "To Work": "الشغل", + "Work Saved": "تم حفظ مكان العمل", + "To Home": "البيت", + "Home Saved": "تم حفظ مكان البيت", + "Destination selected": "تم اختيار الوجهة", + "Now select start pick": "دلوقتي اختار نقطة البداية", + "OK": "تمام", + "Confirm Pick-up Location": "تأكيد موقع الالتقاء", + "Set Location on Map": "حدد الموقع على الخريطة", + "Nearest Car: ~": "أقرب عربية: ~", + "Nearest Car": "أقرب عربية", + "No cars nearby": "مفيش عربيات قريبة", + "Favorite Places": "الأماكن المفضلة", + "No favorite places yet!": "مفيش أماكن مفضلة لسه!", + "from your favorites": "من مفضلتك", + "Back": "رجوع", + "Sign in for a seamless experience": "سجل الدخول لتجربة أفضل", + "Sign In with Google": "تسجيل الدخول باستخدام جوجل", + "Sign in with Apple": "تسجيل الدخول باستخدام آبل", + "Need assistance? Contact us": "محتاج مساعدة؟ كلمنا", + "User not found": "المستخدم مش موجود", + "Email": "البريد الإلكتروني", + "Your email address": "عنوان بريدك الإلكتروني", + "Enter a valid email": "أدخل بريد إلكتروني صحيح", + "Password": "كلمة المرور", + "Your password": "كلمة مرورك", + "Enter your password": "أدخل كلمة المرور", + "Submit": "إرسال", + "Terms of Use & Privacy Notice": "شروط الاستخدام وإشعار الخصوصية", + "Terms of Use": "شروط الاستخدام", + "Privacy Notice": "سياسة الخصوصية", + "By selecting \"I Agree\" below, I confirm that I have read and agree to the": + "بالنقر على \"أوافق\" أدناه، أؤكد أنني قرأت ووافقت على", + "and acknowledge the": "وأقر بـ", + ". I am at least 18 years old.": ". أنا عندي 18 سنة على الأقل.", + "I Agree": "أوافق", + "Continue": "متابعة", + "Enable Location Access": "تفعيل الوصول للموقع", + "We need your location to find nearby drivers for pickups and drop-offs.": + "محتاجين موقعك عشان نلاقي سواقين قريبين للاستلام والتوصيل.", + "Allow Location Access": "السماح بالوصول للموقع", + "You should restart app to change language": + "لازم تقفل التطبيق وتفتحه تاني عشان اللغة تتغير", + "Home Page": "الرئيسية", + "To change Language the App": "لتغيير لغة التطبيق", + "Learn more about our app and mission": + "اعرف أكتر عن تطبيقنا ورسالتنا", + "Promos For Today": "عروض اليوم", + "Choose your ride": "اختار مشوارك", + "Your Journey Begins Here": "رحلتك تبدأ هنا", + "Bonus gift": "هدية إضافية", + "Pay": "ادفع", + "Get": "احصل على", + "Send to Driver Again": "إرسال للسواق مرة تانية", + "Driver Name:": "اسم السائق:", + "No trip data available": "مفيش بيانات للرحلة متاحة", + "Car Plate:": "رقم اللوحة:", + "remaining": "متبقي", "Order Cancelled": "تم إلغاء الطلب", - "you canceled order": "لقد قمت بإلغاء الطلب", - "If you want order to another person": "إذا كنت تريد الطلب لشخص آخر", - "Ok I will go now.": "حسنًا، سأذهب الآن.", - "Hi, I will go now": "مرحبًا، سأذهب الآن.", + "You canceled VIP trip": "ألغيت مشوار VIP", + "Passenger cancelled order": "الراكب ألغى الطلب", + "Your trip is scheduled": "رحلتك مجدولة", + "Don't forget your ride!": "متنساش مشوارك!", + "Trip updated successfully": "تم تحديث الرحلة بنجاح", + "Car Make:": "ماركة العربية:", + "Car Model:": "موديل العربية:", + "Car Color:": "لون العربية:", + "Driver Phone:": "رقم تليفون السواق:", + "Pre-booking": "حجز مسبق", + "Waiting VIP": "انتظار VIP", + "Driver List": "قائمة السائقين", + "Confirm Trip": "تأكيد المشوار", + "Select date and time of trip": "حدد تاريخ ووقت المشوار", + "Date and Time Picker": "اختيار التاريخ والوقت", + "Trip Status:": "حالة المشوار:", + "pending": "قيد الانتظار", + "accepted": "تم القبول", + "rejected": "تم الرفض", + "Apply": "تطبيق", + "Enter your promo code": "أدخل رمز الترويج الخاص بك", + "Apply Promo Code": "تطبيق رمز الترويج", + "Scheduled Time:": "الوقت المحدد:", + "No drivers available": "مفيش سواقين متاحين", + "No drivers available at the moment. Please try again later.": + "مفيش سواقين متاحين دلوقتي. حاول تاني بعدين.", + "you have a negative balance of": "لديك رصيد سلبي قدره", + "Please try again in a few moments": "حاول تاني بعد شوية", + "Unknown Driver": "سائق غير معروف", + "in your": "في محفظتك", + "The driver accepted your order for": "السائق قبل طلبك مقابل", + "wallet due to a previous trip.": "بسبب رحلة سابقة.", + "rides": "مشاوير", + "Add Work": "أضف مكان العمل", + "The reason is": "السبب هو", + "User does not have a wallet #1652": "المستخدم معندوش محفظة", + "Price of trip": "سعر المشوار", + "From:": "من:", + "For Speed and Delivery trips, the price is calculated dynamically. For Comfort trips, the price is based on time and distance": + "بالنسبة لمشاوير السرعة والتوصيل، السعر بيتحدد بشكل تلقائي. أما مشاوير الكمفورت، السعر بيكون على حسب الوقت والمسافة", + "Phone Wallet Saved Successfully": "تم حفظ محفظة الهاتف بنجاح", + "Add wallet phone you use": "ضيف رقم محفظة هاتفك اللي بتستخدمها", + "Update Available": "تحديث متاح", + "Phone number must be exactly 11 digits long": + "رقم التليفون لازم يكون 11 رقم بالظبط", + "Insert Wallet phone number": "أدخل رقم محفظة هاتفك", + "Phone number isn't an Egyptian phone number": + "رقم التليفون ده مش رقم مصري", + "A new version of the app is available. Please update to the latest version.": + "فيه نسخة جديدة من التطبيق متاحة. يرجى التحديث لآخر نسخة.", + "We use location to get accurate and nearest passengers for you": + "بنستخدم الموقع عشان نوصلك بأقرب ركاب وأدقهم ليك", + "This ride is already applied by another driver.": + "المشوار ده اتقبل من سواق تاني خلاص.", + "We use your precise location to find the nearest available driver and provide accurate pickup and dropoff information. You can manage this in Settings.": + "بنستخدم موقعك بالتحديد عشان نلاقي أقرب سواق متاح ونديك معلومات دقيقة عن مكان الاستلام والوصول. ممكن تتحكم في ده من الإعدادات.", + "message From Driver": "رسالة من السواق", + "message From passenger": "رسالة من الراكب", + "Where are you, sir?": "أنا وصلت حضرتك فين.", + "I've been trying to reach you but your phone is off.": + "بحاول أكلمك والتليفون مقفول.", + "Please don't be late": "ياريت متتأخرش", + "Please don't be late, I'm waiting for you at the specified location.": + "ياريت متتأخرش، أنا مستنيك في المكان اللي متحدد.", + "My location is correct. You can search for me using the navigation app": + "موقعي مظبوط. ممكن تدور عليا باستخدام تطبيق الملاحة", + "Hello, I'm at the agreed-upon location": + "أهلاً، أنا في المكان المتفق عليه", + "How much longer will you be?": "قدامك قد إيه؟", + "Phone number is verified before": "تم التحقق من رقم الهاتف قبل كده", + "Change Ride": "تغيير المشوار", + "You can change the destination by long-pressing any point on the map": + "ممكن تغير الوجهة بالضغط مطولاً على أي نقطة في الخريطة", + "Pick from map destination": "اختار وجهتك من الخريطة", + "Pick or Tap to confirm": "اختار أو اضغط للتأكيد", + "Accepted your order": "تم قبول طلبك", + "Order Accepted": "تم قبول الطلب", + "with type": "مع نوع", + "accepted your order at price": "تم قبول طلبك بسعر", + "Cancel Trip from driver": "إلغاء المشوار من السائق", + "you canceled order": "أنت ألغيت الطلب", + "If you want order to another person": "لو عايز تطلب لشخص تاني", + "Ok I will go now.": "تمام، أنا ماشي دلوقتي.", + "Hi, I will go now": "أهلاً، أنا ماشي دلوقتي", "upgrade price": "رفع السعر", - 'Please enter a correct phone': 'يرجى إدخال رقم هاتف صحيح', - 'airport': 'مطار', + "Please enter a correct phone": "يرجى إدخال رقم هاتف صحيح", + "airport": "مطار", "Best choice for a comfortable car with a flexible route and stop points. This airport offers visa entry at this price.": - "أفضل اختيار لسيارة مريحة مع طريق ونقاط توقف مرنة. يقدم هذا المطار تأشيرة دخول بهذا السعر.", + "أفضل اختيار لعربية مريحة بمسار مرن ونقاط توقف. المطار ده بيقدم دخول فيزا بالسعر ده.", "You can upgrade price to may driver accept your order": - "يمكنك رفع السعر حتى يقبل السائق طلبك", + "ممكن تزود السعر عشان السواق يقبل طلبك", "Change Route": "تغيير المسار", - "No Captain Accepted Your Order": "لا يوجد كابتن قبل الطلب الخاص بك", + "No Captain Accepted Your Order": "مفيش كابتن قبل طلبك", "We are looking for a captain but the price may increase to let a captain accept": - "نحن نبحث عن كابتن ولكن قد يرتفع السعر للسماح لكابتن بقبول الطلب", - "No, I want to cancel this trip": "لا، أريد إلغاء هذه الرحلة", - 'Trip Cancelled. The cost of the trip will be added to your wallet.': - "تم إلغاء الرحلة. سيتم إضافة تكلفة الرحلة إلى محفظتك.", - + "بندور على كابتن بس ممكن السعر يزيد عشان كابتن يقبل", + "No, I want to cancel this trip": "لأ، أنا عايز ألغي المشوار ده", + "Trip Cancelled. The cost of the trip will be added to your wallet.": + "تم إلغاء الرحلة. هيتم إضافة تكلفة الرحلة لمحفظتك.", "Attention": "تنبيه", "Trip Cancelled. The cost of the trip will be deducted from your wallet.": - "تم إلغاء الرحلة. سيتم خصم تكلفة الرحلة من محفظتك.", + "تم إلغاء الرحلة. هيتخصم تكلفة الرحلة من محفظتك.", "You will be charged for the cost of the driver coming to your location.": - "سيتم خصم تكلفة قدوم السائق إلى موقعك.", + "هتتحاسب على تكلفة مجيء السواق لموقعك.", "reject your order.": "رفض طلبك.", "Order Under Review": "الطلب قيد المراجعة", "is reviewing your order. They may need more information or a higher price.": - "يتم مراجعة طلبك. قد يحتاجون إلى مزيد من المعلومات أو سعر أعلى.", - "The driver canceled your ride.": "ألغى السائق رحلتك.", + "بيراجع طلبك. ممكن يحتاجوا معلومات أكتر أو سعر أعلى.", + "The driver canceled your ride.": "السواق ألغى مشوارك.", "We haven't found any drivers yet. Consider increasing your trip fee to make your offer more attractive to drivers.": - "لم نجد أي سائقين بعد. ضع في اعتبارك زيادة رسوم رحلتك لجعل عرضك أكثر جاذبية للسائقين.", - "Increase Your Trip Fee (Optional)": "زيادة رسوم رحلتك (اختياري)", - 'Vibration': "اهتزاز‏", - 'Resend code': "إعادة إرسال الرمز", - "Sign in with Apple": "تسجيل الدخول باستخدام Apple", + "ملقيناش أي سواقين لسه. فكر تزود سعر المشوار عشان عرضك يكون جذاب أكتر للسواقين.", + "Increase Your Trip Fee (Optional)": "زود سعر مشوارك (اختياري)", + "Vibration": "اهتزاز", + "Resend code": "إعادة إرسال الرمز", "token change": "تغيير الرمز", "change device": "تغيير الجهاز", "Device Change Detected": "تم اكتشاف تغيير الجهاز", "You can only use one device at a time. This device will now be set as your active device.": - "يمكنك استخدام جهاز واحد في المرة الواحدة. سيتم الآن تعيين هذا الجهاز كجهازك النشط.", - "Click here point": "انقر هنا", // Click here (literal translation) - - "Are you want to change": "هل تريد التغيير؟", - 'by': 'ب', - "Enter your complaint here": "أدخل شكواك هنا", - "Complaint": "شكوى", + "ممكن تستخدم جهاز واحد بس في المرة الواحدة. الجهاز ده هيتعين دلوقتي كجهازك النشط.", + "Click here point": "اضغط هنا", + "Are you want to change": "عايز تغير؟", + "by": "بواسطة", + "Enter your complaint here": "اكتب شكوتك هنا", "Please enter your complaint.": "الرجاء إدخال شكواك.", - "Submit": "إرسال", "Complaint data saved successfully": "تم حفظ بيانات الشكوى بنجاح", "Trip Monitor": "مراقبة الرحلة", - "Insert SOS Phone": "أدخل رقم الهاتف للطوارئ", - "Add SOS Phone": "أضف رقم الهاتف للطوارئ", + "Insert SOS Phone": "أدخل رقم طوارئ", + "Add SOS Phone": "أضف رقم طوارئ", "Trip Monitoring": "مراقبة الرحلة", - '''Dear , - - 🚀 I have just started an exciting trip and I would like to share the details of my journey and my current location with you in real-time! Please download the SEFER app. It will allow you to view my trip details and my latest location. - - 👉 Download link: - Android [https://play.google.com/store/apps/details?id=com.mobileapp.store.ride] - iOS [https://getapp.cc/app/6458734951] - - I look forward to keeping you close during my adventure! - - SEFER ,''': '''عزيزي ، - - -🚀 لقد بدأت للتو رحلة مثيرة وأود مشاركة تفاصيل رحلتي وموقعي الحالي معك في الوقت الفعلي! يرجى تنزيل تطبيق سفر. سيمكنك ذلك من عرض تفاصيل رحلتي وموقعي الأخير. - - -👉 رابط التحميل: -Android [https://play.google.com/store/apps/details?id=com.mobileapp.store.ride] -iOS [https://getapp.cc/app/6458734951] - - -أتطلع إلى إبقائك قريبًا خلال مغامرتي! - - -سفر ،''', - "Send Sefer app to him": "أرسل له تطبيق سفر", + "Dear ,\n\n 🚀 I have just started an exciting trip and I would like to share the details of my journey and my current location with you in real-time! Please download the SEFER app. It will allow you to view my trip details and my latest location.\n\n 👉 Download link: \n Android [https://play.google.com/store/apps/details?id=com.mobileapp.store.ride]\n iOS [https://getapp.cc/app/6458734951]\n\n I look forward to keeping you close during my adventure!\n\n SEFER ,": + "عزيزي،\n\n🚀 بدأت للتو رحلة مثيرة وأود مشاركة تفاصيل رحلتي وموقعي الحالي معك في الوقت الفعلي! يرجى تنزيل تطبيق سفر. سيسمح لك بعرض تفاصيل رحلتي وموقعي الأخير.\n\n👈 رابط التحميل:\nAndroid [https://play.google.com/store/apps/details?id=com.mobileapp.store.ride]\niOS [https://getapp.cc/app/6458734951]\n\nأتطلع إلى إبقائك على اطلاع دائم بمغامرتي!\n\nسفر،", + "Send Sefer app to him": "ابعتله تطبيق سفر", "No passenger found for the given phone number": - "لم يتم العثور على راكب لرقم الهاتف المعطى", - "No user found for the given phone number": - "لم يتم العثور على مستخدم لرقم الهاتف المعطى", - "This price is": "هذا السعر هو", + "مفيش راكب بالرقم ده", + "No user found for the given phone number": "مفيش مستخدم بالرقم ده", + "This price is": "السعر ده", "Work": "عمل", "Add Home": "أضف منزل", - "Notifications": "إشعارات", - '💳 Pay with Credit Card': "ادفع باستخدام بطاقة الائتمان💳", - "⚠️ You need to choose an amount!": "⚠️ يجب عليك اختيار مبلغ!", - '💰 Pay with Wallet': "ادفع باستخدام المحفظة", + "Notifications": "الإشعارات", + "💳 Pay with Credit Card": "ادفع بالبطاقة الائتمانية 💳", + "⚠️ You need to choose an amount!": "⚠️ لازم تختار مبلغ!", + "💰 Pay with Wallet": "ادفع من المحفظة", "You must restart the app to change the language.": - "يجب إعادة تشغيل التطبيق لتغيير اللغة", + "لازم تقفل التطبيق وتفتحه تاني عشان اللغة تتغير.", "joined": "انضم", "Driver joined the channel": "السائق انضم للقناة", "Driver left the channel": "السائق غادر القناة", - "Call Page": "صفحة المكالمة", + "Call Page": "صفحة الاتصال", "Call End": "إنهاء المكالمة", "Call Left": "مكالمات متبقية", - "\$ Next as Cash \$!": " نقداً !", - "To use Wallet charge it": "لاستخدام المحفظة، قم بشحنها", + r"$ Next as Cash $!": " نقداً !", + "To use Wallet charge it": "عشان تستخدم المحفظة اشحنها", "We are searching for the nearest driver to you": - "نبحث عن أقرب سائق إليك", + "بندورلك على أقرب سواق ليك", "Best choice for cities": "أفضل اختيار للمدن", "Rayeh Gai: Round trip service for convenient travel between cities, easy and reliable.": - " رايح جاي: خدمة ذهاب وعودة للسفر المريح بين المدن، سهلة وموثوقة.", - "Rayeh Gai": "رايح جاي ", - "This trip is for women only": "هذه الرحلة للنساء فقط", - "Total budgets on month": "إجمالي الميزانية لهذا الشهر", - "You have call from driver": " لديك مكالمة من السائق", + "رايح جاي: خدمة للذهاب والعودة لسفر مريح بين المدن، سهلة وموثوقة.", + "Rayeh Gai": "رايح جاي", + "This trip is for women only": "المشوار ده للسيدات فقط", + "Total budgets on month": "إجمالي الميزانية الشهرية", + "You have call from driver": "عندك مكالمة من السواق", "Comfort": "كمفورت", "Speed": "سبيد", "Driver already has 2 trips within the specified period.": - 'السائق لديه بالفعل رحلتان خلال الفترة المحددة.', + "السائق عنده بالفعل مشوارين خلال الفترة المحددة.", "The invitation was sent successfully": "تم إرسال الدعوة بنجاح", "Lady": "ليدي", "You should select your country": "يجب عليك اختيار بلدك", "Scooter": "سكوتر", - 'A trip with a prior reservation, allowing you to choose the best captains and cars.': - 'مشوار بحجز مسبق مع إمكانية اختيارك لأفضل الكباتن والسيارات', - "Mishwar Vip": "‏مشوار VIP", - 'The driver waiting you in picked location .': - "السائق ينتظرك في موقع الركوب.", - 'About Us': "نبذة عنا", + "A trip with a prior reservation, allowing you to choose the best captains and cars.": + "مشوار بحجز مسبق، تقدر تختار فيه أفضل الكباتن والعربيات.", + "Mishwar Vip": "مشوار VIP", + "The driver waiting you in picked location .": + "السائق منتظرك في مكان الالتقاء.", + "About Us": "عن التطبيق", "You can change the vibration feedback for all buttons": - "يمكنك تغيير اهتزاز الرج لجميع الأزرار", - "Most Secure Methods": "أساليب الأمان الأكثر فاعلية", - "In-App VOIP Calls": "مكالمات VOIP داخل التطبيق", - "Recorded Trips for Safety": "تسجيل الرحلات من أجل السلامة", + "ممكن تغير اهتزاز الأزرار", + "Most Secure Methods": "أكثر طرق الأمان", + "In-App VOIP Calls": "مكالمات صوتية داخل التطبيق", + "Recorded Trips for Safety": "تسجيل الرحلات للأمان", "\nWe also prioritize affordability, offering competitive pricing to make your rides accessible.": - "\nكما أننا نضع توفير التكاليف في أولوية اهتماماتنا، ونقدم أسعاراً منافسة لجعل رحلاتك في متناول اليد.", - 'SEFER is a ride-sharing app designed with your safety and affordability in mind. We connect you with reliable drivers in your area, ensuring a convenient and stress-free travel experience.\n\nHere are some of the key features that set us apart:': - "SEFER: تطبيق مشاركة الرحلات يضع سلامتك وادخارك في المقدمة SEFER هو تطبيق مشاركة رحلات مصمم مع وضع سلامتك وتوفيرك في الاعتبار. نربطك بسائقين موثوقين في منطقتك، ونضمن لك تجربة سفر مريحة وخالية من الضغوط.فيما يلي بعض الميزات الرئيسية التي تميزنا:", - 'Sign In by Apple': 'تسجيل الدخول باستخدام Apple', - 'Sign In by Google': 'تسجيل الدخول باستخدام Google', - "How do I request a ride?": "كيف أطلب رحلة؟", + "\nكما نولي أهمية كبيرة للأسعار المناسبة، ونقدم أسعارًا تنافسية لجعل مشاويرك في متناول الجميع.", + "SEFER is a ride-sharing app designed with your safety and affordability in mind. We connect you with reliable drivers in your area, ensuring a convenient and stress-free travel experience.\n\nHere are some of the key features that set us apart:": + "سفر هو تطبيق لمشاركة المشاوير مصمم مع وضع سلامتك وتكلفة المشوار في الاعتبار. نوصلك بسائقين موثوقين في منطقتك، ونضمن لك تجربة سفر مريحة وبدون قلق.\n\nإليك بعض المميزات الأساسية اللي بتميزنا:", + "Sign In by Apple": "تسجيل الدخول باستخدام Apple", + "Sign In by Google": "تسجيل الدخول باستخدام Google", + "How do I request a ride?": "إزاي أطلب مشوار؟", "Step-by-step instructions on how to request a ride through the Sefer app.": - "تعليمات خطوة بخطوة حول كيفية طلب رحلة من خلال تطبيق Sefer.", + "تعليمات خطوة بخطوة عن كيفية طلب مشوار من خلال تطبيق سفر.", "What types of vehicles are available?": - "ما هي أنواع المركبات المتاحة؟", + "إيه أنواع العربيات المتاحة؟", "Sefer offers a variety of vehicle options to suit your needs, including economy, comfort, and luxury. Choose the option that best fits your budget and passenger count.": - "توفر Sefer مجموعة متنوعة من خيارات المركبات لتناسب احتياجاتك، بما في ذلك الاقتصادية والمريحة والفخمة. اختر الخيار الذي يناسب ميزانيتك وعدد الركاب.", - "How can I pay for my ride?": "كيف يمكنني الدفع لرحلتي؟", + "سفر بتقدملك اختيارات متنوعة للعربيات تناسب احتياجاتك، منها اقتصادي ومريح وفاخر. اختار اللي يناسب ميزانيتك وعدد الركاب.", + "How can I pay for my ride?": "إزاي أدفع تمن المشوار؟", "Sefer offers multiple payment methods for your convenience. Choose between cash payment or credit/debit card payment during ride confirmation.": - "توفر Sefer طرق دفع متعددة لراحتك. اختر بين الدفع نقدًا أو بطاقة ائتمان/خصم أثناء تأكيد الرحلة.", - "Can I cancel my ride?": "هل يمكنني إلغاء رحلتي؟", + "سفر بتقدملك طرق دفع متعددة لراحتك. اختار بين الدفع كاش أو ببطاقة الائتمان/الخصم وأنت بتأكد المشوار.", + "Can I cancel my ride?": "ممكن ألغي المشوار؟", "Yes, you can cancel your ride under certain conditions (e.g., before driver is assigned). See the Sefer cancellation policy for details.": "نعم، يمكنك إلغاء رحلتك في ظل ظروف معينة (مثل قبل تعيين السائق). اطلع على سياسة الإلغاء في Sefer للحصول على التفاصيل.", "Driver Registration & Requirements": "تسجيل السائقين والمتطلبات", @@ -259,16 +304,16 @@ iOS [https://getapp.cc/app/6458734951] "ما هي تدابير السلامة التي تقدمها Sefer؟", "Sefer prioritizes your safety. We offer features like driver verification, in-app trip tracking, and emergency contact options.": "تُولي Sefer أهمية كبيرة لسلامتك. نحن نقدم ميزات مثل التحقق من هوية السائق ، وتتبع الرحلات داخل التطبيق ، وخيارات الاتصال في حالات الطوارئ.", - 'Frequently Questions': 'الأسئلة الشائعة', - "User does not exist.": 'المستخدم غير موجود', - 'We need your phone number to contact you and to help you.': - 'نحتاج إلى رقم هاتفك للتواصل معك ولمساعدتك', - 'You will recieve code in sms message': 'ستتلقى رمزًا في رسالة SMS', - 'Please enter': 'يرجى إدخال', - 'We need your phone number to contact you and to help you receive orders.': + "Frequently Questions": "الأسئلة الشائعة", + "User does not exist.": "المستخدم غير موجود", + "We need your phone number to contact you and to help you.": + "نحتاج إلى رقم هاتفك للتواصل معك ولمساعدتك", + "You will recieve code in sms message": "ستتلقى رمزًا في رسالة SMS", + "Please enter": "يرجى إدخال", + "We need your phone number to contact you and to help you receive orders.": "نحتاج إلى رقم هاتفك للتواصل معك ولمساعدتك في تلقي الطلبات.", - 'The full name on your criminal record does not match the one on your driver’s license. Please verify and provide the correct documents.': - 'الاسم الكامل في سجلك الجنائي لا يتطابق مع الاسم الموجود في رخصة القيادة الخاصة بك. يرجى التحقق وتقديم الوثائق الصحيحة.', + "The full name on your criminal record does not match the one on your driver’s license. Please verify and provide the correct documents.": + "الاسم الكامل في سجلك الجنائي لا يتطابق مع الاسم الموجود في رخصة القيادة الخاصة بك. يرجى التحقق وتقديم الوثائق الصحيحة.", "The national number on your driver’s license does not match the one on your ID document. Please verify and provide the correct documents.": "الرقم الوطني على رخصة القيادة الخاصة بك لا يتطابق مع الرقم الموجود على وثيقة الهوية الخاصة بك. يرجى التحقق وتقديم الوثائق الصحيحة.", "Capture an Image of Your Criminal Record": @@ -279,19 +324,19 @@ iOS [https://getapp.cc/app/6458734951] "Capture an Image of Your ID Document front": "التقط صورة للواجهة الأمامية لوثيقة هويتك", "NationalID": "الرقم القومي", - 'You can share the SEFER App with your friends and earn rewards for rides they take using your code': - 'يمكنك مشاركة تطبيق SEFER مع أصدقائك وكسب مكافآت من الرحلات التي يقومون بها باستخدام كودك.', + "You can share the SEFER App with your friends and earn rewards for rides they take using your code": + "يمكنك مشاركة تطبيق SEFER مع أصدقائك وكسب مكافآت من الرحلات التي يقومون بها باستخدام كودك.", "FullName": "الاسم الكامل", "No invitation found yet!": "لم يتم العثور على دعوات حتى الآن!", "InspectionResult": "نتيجة الفحص", - "Criminal Record": "السجل الجنائي", 'Share App': 'شارك التطبيق', + "Criminal Record": "السجل الجنائي", + "Share App": "شارك التطبيق", "The email or phone number is already registered.": "البريد الإلكتروني أو رقم الهاتف مسجل بالفعل.", - 'To become a ride-sharing driver on the Sefer app, you need to upload your driver\'s license, ID document, and car registration document. Our AI system will instantly review and verify their authenticity in just 2-3 minutes. If your documents are approved, you can start working as a driver on the Sefer app. Please note, submitting fraudulent documents is a serious offense and may result in immediate termination and legal consequences.': - 'لِتُصْبِحَ سَائِقَاً لِلرُّكوبِ المُشْتَرَكِ عَلَى تَطْبِيق سَفَر، يَجِبُ عَلَيْكَ تَحْمِيل رُخْصَةِ القِيَادَةِ، وَثِيقَةِ الهُوِيَّةِ، وَوَثِيقَةَ تَسْجِيل السَّيَّارَةِ. سَيَقُومُ نِظَامُ الذَّكَاءِ الاِصْطِنَاعِيِّ لَدَيْنَا بِمُرَاجَعَةِ وَتَحْقِيقِ صِحَّةِ الوَثَائِقِ فِي غُضُونِ ٢-٣ دَقَائِقَ فَقَطْ. إِذَا تَمَّتْ المُوَافَقَةُ عَلَى وَثَائِقِكَ، يُمْكِنُكَ البَدْءُ فِي العَمَلِ كَسَائِقٍ عَلَى تَطْبِيق سَفَر. يُرْجَى مُلَاحَظَةُ، تَقْدِيمُ وَثَائِقَ مُزَورَةٍ يُعَدُّ جَرِيمَةً خَطِيرَةً وَقَدْ يَتَرَتَّبُ عَلَيْهِ اِنهَاءُ الحِسَابِ فَوْرِيَّاً وَعَوَاقِبُ قَانُونِيَّة.', + "To become a ride-sharing driver on the Sefer app, you need to upload your driver's license, ID document, and car registration document. Our AI system will instantly review and verify their authenticity in just 2-3 minutes. If your documents are approved, you can start working as a driver on the Sefer app. Please note, submitting fraudulent documents is a serious offense and may result in immediate termination and legal consequences.": + "لِتُصْبِحَ سَائِقَاً لِلرُّكوبِ المُشْتَرَكِ عَلَى تَطْبِيق سَفَر، يَجِبُ عَلَيْكَ تَحْمِيل رُخْصَةِ القِيَادَةِ، وَثِيقَةِ الهُوِيَّةِ، وَوَثِيقَةَ تَسْجِيل السَّيَّارَةِ. سَيَقُومُ نِظَامُ الذَّكَاءِ الاِصْطِنَاعِيِّ لَدَيْنَا بِمُرَاجَعَةِ وَتَحْقِيقِ صِحَّةِ الوَثَائِقِ فِي غُضُونِ ٢-٣ دَقَائِقَ فَقَطْ. إِذَا تَمَّتْ المُوَافَقَةُ عَلَى وَثَائِقِكَ، يُمْكِنُكَ البَدْءُ فِي العَمَلِ كَسَائِقٍ عَلَى تَطْبِيق سَفَر. يُرْجَى مُلَاحَظَةُ، تَقْدِيمُ وَثَائِقَ مُزَورَةٍ يُعَدُّ جَرِيمَةً خَطِيرَةً وَقَدْ يَتَرَتَّبُ عَلَيْهِ اِنهَاءُ الحِسَابِ فَوْرِيَّاً وَعَوَاقِبُ قَانُونِيَّة.", "Documents check": "فحص الوثائق", "Driver's License": "رخصة القيادة", - "for your first registration!": "للتسجيل الأول!", "Get it Now!": "احصل عليه الآن!", "before": "قبل", @@ -305,50 +350,48 @@ iOS [https://getapp.cc/app/6458734951] "Install our app:": "قم بتثبيت تطبيقنا:", "Invite another driver and both get a gift after he completes 100 trips!": "ادع صديقًا ليكون سائقًا واحصلا على هدية بعد إكماله 100 مشوار!", - "Share App": "شارك التطبيق", - "Invite": "دعوة", "Are you sure?": "هل أنت متأكد؟", + "Invite": "دعوة", + "Are you sure?": "هل أنت متأكد؟", "This will delete all recorded files from your device.": "سيؤدي هذا إلى حذف جميع الملفات المسجلة من جهازك.", "Select a file": "اختر ملفاً", - "Select a File": "اختر ملفاً", "Delete": "حذف", - 'attach audio of complain': 'إرفاق صوت للشكوى', + "Select a File": "اختر ملفاً", + "Delete": "حذف", + "attach audio of complain": "إرفاق صوت للشكوى", "Phone Number Check": "فحص رقم الهاتف", "Drivers received orders": "السائقون استقبلوا الطلبات", - 'No audio files recorded.': 'لا توجد ملفات صوتية مسجلة.', - 'This is for delivery or a motorcycle.': + "No audio files recorded.": "لا توجد ملفات صوتية مسجلة.", + "This is for delivery or a motorcycle.": "هذا للتوصيل أو للدراجة النارية.", "We will look for a new driver.\nPlease wait.": "سوف نبحث عن سائق جديد.\nيرجى الانتظار", "Sefer Reminder": "تطبيق سفر", "It's time to check the Sefer app!": "حان وقت استخدام تطبيق سفر", - "The email or phone number is already registered.": - "البريد الإلكتروني أو رقم الهاتف مسجل بالفعل.", "you must insert token code": "يجب إدخال رمز التحقق.", "Something went wrong. Please try again.": "حدث خطأ ما. يرجى المحاولة مرة أخرى.", - "This is for delivery or a motorcycle.": - "هذا للتوصيل أو للدراجة النارية.", "Trip Details": "تفاصيل الرحلة", - 'The context does not provide any complaint details, so I cannot provide a solution to this issue. Please provide the necessary information, and I will be happy to assist you.': + "The context does not provide any complaint details, so I cannot provide a solution to this issue. Please provide the necessary information, and I will be happy to assist you.": "لا تتوفر تفاصيل الشكوى في السياق، لذا لا أستطيع تقديم حل لهذه المشكلة. يرجى تقديم المعلومات اللازمة، وسأكون سعيدًا بمساعدتك", - 'Submit Your Complaint': "أرسل شكواك", + "Submit Your Complaint": "أرسل شكواك", "Date": "التاريخ", "Price": "السعر", "Status": "الحالة", "Choose from contact": "اختر من جهات الاتصال", - 'attach correct audio': "إرفاق صوت للشكوى", - 'be sure': 'كن متأكدًا', - 'Audio uploaded successfully.': 'تم رفع الصوت بنجاح', + "attach correct audio": "إرفاق صوت للشكوى", + "be sure": "كن متأكدًا", + "Audio uploaded successfully.": "تم رفع الصوت بنجاح", "Perfect for passengers seeking the latest car models with the freedom to choose any route they desire": "مثالي للركاب الذين يبحثون عن أحدث موديلات السيارات مع حرية اختيار أي طريق يرغبون به", "Share this code with your friends and earn rewards when they use it!": "شارك هذا الرمز مع أصدقائك واحصل على مكافآت عند استخدامهم له!", "Enter phone": "أدخل رقم الهاتف", - 'You deserve the gift': "أنت تستحق الهدية", + "You deserve the gift": "أنت تستحق الهدية", "complete, you can claim your gift": " يمكنك المطالبة بهديتك", "When": "‏عندما يكمل", "Enter driver's phone": "أدخل رقم هاتف السائق", - "Send Invite": "أرسل الدعوة", "Show Invitations": "عرض الدعوات", + "Send Invite": "أرسل الدعوة", + "Show Invitations": "عرض الدعوات", "License Type": "نوع الرخصة", "National Number": "الرقم الوطني", "Name (Arabic)": "الاسم بالعربي", @@ -372,7 +415,6 @@ iOS [https://getapp.cc/app/6458734951] "ID Documents Front": "الوجه الأمامي لوثائق الهوية", "First Name": "الاسم الأول", "CardID": "رقم البطاقة", - "Full Name": "الاسم الكامل", "Vehicle Details Front": "تفاصيل المركبة ‏الوجه الأمامية", "Plate Number": "رقم اللوحة", "Owner Name": "اسم المالك", @@ -388,16 +430,16 @@ iOS [https://getapp.cc/app/6458734951] "Inspection Date": "تاريخ الفحص", "Capture an Image of Your car license back": "التقط صورة للوجه الخلفي لرخصة سيارتك", - 'Capture an Image of Your Driver’s License': - 'التقط صورة لرخصة قيادتك', - 'Sign in with Google for easier email and name entry': - 'سجل دخولك باستخدام جوجل لتسجيل بريدك الإلكتروني واسمك بسهولة', - 'You will choose allow all the time to be ready receive orders': - 'ستختار السماح طوال الوقت لتكون جاهزًا لاستقبال الطلبات', - 'Welcome to Sefer!': 'مرحبا بكم في سفر!', - 'Get to your destination quickly and easily.': - 'وصول إلى وجهتك بسرعة وسهولة.', - 'Enjoy a safe and comfortable ride.': 'استمتع برحلة آمنة ومريحة.', + "Capture an Image of Your Driver’s License": + "التقط صورة لرخصة قيادتك", + "Sign in with Google for easier email and name entry": + "سجل دخولك باستخدام جوجل لتسجيل بريدك الإلكتروني واسمك بسهولة", + "You will choose allow all the time to be ready receive orders": + "ستختار السماح طوال الوقت لتكون جاهزًا لاستقبال الطلبات", + "Welcome to Sefer!": "مرحبا بكم في سفر!", + "Get to your destination quickly and easily.": + "وصول إلى وجهتك بسرعة وسهولة.", + "Enjoy a safe and comfortable ride.": "استمتع برحلة آمنة ومريحة.", "Choose Language": "اختر اللغة", "Login": "تسجيل الدخول", "Pay with Wallet": "ادفع باستخدام المحفظة", @@ -408,7 +450,6 @@ iOS [https://getapp.cc/app/6458734951] "Enter your phone number": "أدخل رقم هاتفك", "Please enter your phone number.": "يرجى إدخال رقم هاتفك.", "Please enter Your Password.": "يرجى إدخال كلمة المرور.", - "if you dont have account": "إذا لم يكن لديك حساب", "Register": "تسجيل", "Accept Ride's Terms & Review Privacy Notice": @@ -440,7 +481,8 @@ iOS [https://getapp.cc/app/6458734951] "To : ": "إِلَى: ", "Add Promo": "إضَافَة بَرُومُو", "Confirm Selection": "تَأْكِيد الاخْتِيَار", - "distance is": "المَسَافَة", "About Us": "عنّا", + "distance is": "المَسَافَة", + "About Us": "عنّا", "SEFER LLC": "شركة SEFER", "Egypt's pioneering ride-sharing service, proudly developed by Arabian and local owners. We prioritize being near you – both our valued passengers and our dedicated captains.": "أول خدمة مشاركة ركوب في مصر، تم تطويرها بفخر من قبل مالكين عرب ومحليين. نحن نركز على أن نكون قريبين منك - سواء كنت راكبًا قيمًا أو قائدًا مخلصًا.", @@ -467,608 +509,570 @@ iOS [https://getapp.cc/app/6458734951] "Sefer offers a variety of options including Economy, Comfort, and Luxury to suit your needs and budget.": "يوفر Sefer مجموعة متنوعة من الخيارات بما في ذلك الاقتصادية، المريحة، والفاخرة لتلبية احتياجاتك وميزانيتك.", "Payments": "المدفوعات", - "How can I pay for my ride?": "كيف يمكنني دفع تكلفة رحلتي؟", + "How can I pay for my ride?": "إزاي ممكن أدفع تمن المشوار؟", "You can pay for your ride using cash or credit/debit card. You can select your preferred payment method before confirming your ride.": - "يمكنك دفع تكلفة رحلتك نقدًا أو باستخدام بطاقة ائتمان/خصم. يمكنك اختيار طريقة الدفع المفضلة قبل تأكيد الرحلة.", + "ممكن تدفع تمن مشوارك كاش أو ببطاقة الائتمان/الخصم. تقدر تختار طريقة الدفع اللي تفضلها قبل ما تأكد المشوار.", "Ride Management": "إدارة الرحلات", - "Can I cancel my ride?": "هل يمكنني إلغاء رحلتي؟", + "Can I cancel my ride?": "ممكن ألغي المشوار؟", "Yes, you can cancel your ride, but please note that cancellation fees may apply depending on how far in advance you cancel.": - "نعم، يمكنك إلغاء رحلتك، ولكن يرجى ملاحظة أن رسوم الإلغاء قد تنطبق اعتمادًا على توقيت الإلغاء.", - "For Drivers": "للسائقين", - "Driver Registration & Requirements": "التسجيل ومتطلبات السائقين", - "Driver Registration": "تسجيل السائق", + "أيوة، ممكن تلغي مشوارك، بس يرجى ملاحظة إن فيه رسوم إلغاء ممكن تتطبق حسب الوقت اللي بتلغي فيه قبلها قد إيه.", + "For Drivers": "للسواقين", + "Driver Registration & Requirements": "تسجيل ومتطلبات السواقين", + "Driver Registration": "تسجيل السواق", "To register as a driver or learn about the requirements, please visit our website or contact Sefer support directly.": - "لتسجيل نفسك كسائق أو لمعرفة المتطلبات، يرجى زيارة موقعنا الإلكتروني أو الاتصال بدعم Sefer مباشرة.", + "علشان تسجل كسواق أو تعرف المتطلبات، يرجى زيارة موقعنا الإلكتروني أو الاتصال بدعم سفر مباشرةً.", "Visit Website/Contact Support": "زيارة الموقع/الاتصال بالدعم", "Close": "إغلاق", - "We are searching for the nearest driver": "نحن نبحث عن أقرب سائق", + "We are searching for the nearest driver": "بندور على أقرب سواق", "Communication": "التواصل", "How do I communicate with the other party (passenger/driver)?": - "كيف يمكنني التواصل مع الطرف الآخر (الراكب/السائق)؟", + "إزاي أتواصل مع الطرف التاني (الراكب/السواق)؟", "You can communicate with your driver or passenger through the in-app chat feature once a ride is confirmed.": - "يمكنك التواصل مع السائق أو الراكب من خلال ميزة الدردشة داخل التطبيق بمجرد تأكيد الرحلة.", + "ممكن تتواصل مع السواق أو الراكب من خلال خاصية الشات جوة التطبيق أول ما المشوار يتأكد.", "Safety & Security": "الأمان والحماية", "What safety measures does Sefer offer?": - "ما هي تدابير الأمان التي يوفرها Sefer؟", + "إيه إجراءات الأمان اللي بيقدمها سفر؟", "Sefer offers various safety features including driver verification, in-app trip tracking, emergency contact options, and the ability to share your trip status with trusted contacts.": - "يوفر Sefer ميزات أمان مختلفة بما في ذلك التحقق من السائق، تتبع الرحلة داخل التطبيق، خيارات الاتصال في حالات الطوارئ، والقدرة على مشاركة حالة رحلتك مع جهات اتصال موثوقة.", + "سفر بيقدم مميزات أمان متنوعة زي التحقق من السواق، تتبع الرحلة جوة التطبيق، خيارات الاتصال في حالات الطوارئ، وإمكانية مشاركة حالة رحلتك مع جهات اتصال موثوقة.", "Enjoy competitive prices across all trip options, making travel accessible.": - "استمتع بأسعار تنافسية لجميع خيارات الرحلات، مما يجعل السفر متاحًا.", + "استمتع بأسعار تنافسية على كل خيارات الرحلات، وده بيخلي السفر سهل الوصول ليه.", "Variety of Trip Choices": "خيارات رحلات متنوعة", "Choose the trip option that perfectly suits your needs and preferences.": - "اختر خيار الرحلة الذي يناسب احتياجاتك وتفضيلاتك.", + "اختار خيار الرحلة اللي يناسب احتياجاتك وتفضيلاتك بالظبط.", "Your Choice, Our Priority": "اختيارك هو أولويتنا", "Because we are near, you have the flexibility to choose the ride that works best for you.": - "لأننا قريبون، لديك المرونة لاختيار الرحلة التي تناسبك.", - "duration is": "المُدَّة", "Setting": "الإعدادات", + "علشان إحنا قريبين، عندك المرونة تختار المشوار اللي يناسبك.", + "duration is": "المدة", + "Setting": "الإعدادات", "Find answers to common questions": "اعثر على إجابات للأسئلة الشائعة", - "I don't need a ride anymore": "لا أحتاج إلى رحلة بعد الآن", - "I was just trying the application": "كنت أجرب التطبيق فقط", - "No driver accepted my request": "لم يقبل أي سائق طلبي", + "I don't need a ride anymore": "أنا مش محتاج مشوار تاني", + "I was just trying the application": "كنت بجرب التطبيق بس", + "No driver accepted my request": "مفيش سواق قبل الطلب بتاعي", "I added the wrong pick-up/drop-off location": - "أضفت موقع استلام/توصيل خاطئ", - "I don't have a reason": "ليس لدي سبب", + "أنا ضفت مكان استلام/توصيل غلط", + "I don't have a reason": "ماليش سبب", "Other": "أخرى", "Can we know why you want to cancel Ride ?": - "هَل يُمْكِنُنَا مَعْرِفَة سَبَب رَغْبَتِكَ فِي إلْغَاء الرِّحْلَة؟", - "Cancel Ride": "إلْغَاء الرِّحْلَة", - "Add Payment Method": "إضَافَة طَرِيقَة الدَّفْع", - "Your Wallet balance is ": "رَصِيد المَحْفَظَة الخَاصَّة بِكَ ", - "Ride Wallet": "مَحْفَظَة الرِّحْلَة", - "Payment Method": "طَرِيقَة الدَّفْع", - "Type here Place": "اكْتُبْ هُنَا المَكَان", - "Are You sure to ride to": - "هَل أَنْتَ مُتَأَكِّد مِنْ رَغْبَتِكَ فِي الذَّهَاب إِلَى", - "Confirm": "تَأْكِيد", - "Back": "رَجُوع", - "You are Delete": "أَنْتَ عَلَى وَشْك الحَذْف", - "Deleted": "تَمَّ الحَذْف", - "You Dont Have Any places yet !": - "لَيْسَ لَدَيْكَ أَيُّ أَمَاكِن بَعْد!", - "Favorite Places": "الأَمَاكِن المُفَضَّلَة", - "From : Current Location": "مِنْ: المَوْقِع الحَالِي", - "Where to": "إِلَى أَيْن", - // "Notifications": "الإشْعَارَات", - "Profile": "الملف الشَّخْصِي", - "Home": "الصَّفْحَة الرَّئِيسِيَّة", - "My Cared": "المُهْتَمَّ بِهِ", - "Add Card": "إضَافَة بَطَاقَة", - "Add Credit Card": "إضَافَة بَطَاقَة ائْتِمَان", - "Please enter the cardholder name": - "يَرْجَى إِدْخَال اسْم حَامِل البَطَاقَة", - "Please enter the expiry date": - "يَرْجَى إِدْخَال تَارِيخ انْتِهَاء الصَّلَاحِيَّة", - "Please enter the CVV code": "يَرْجَى إِدْخَال رَمْز CVV", - "Go To Favorite Places": "الانْتِقَال إِلَى الأَمَاكِن المُفَضَّلَة", - "Go to this Target": "الانْتِقَال إِلَى هَذَا الهَدَف", - "My Profile": "مَلَفِي الشَّخْصِي", - "Sign Out": "تَسْجِيل الخُرُوج", - - "Are you want to go to this site": - "هَل تَرْغَب فِي الانْتِقَال إِلَى هَذَا المَوْقِع", - "MyLocation": "مَوْقِعِي", - "my location": "مَوْقِعِي", - "Target": "هَدَف", + "ممكن نعرف ليه عايز تلغي المشوار؟", + "Cancel Ride": "إلغاء المشوار", + "Add Payment Method": "إضافة طريقة الدفع", + "Your Wallet balance is ": "رصيد محفظتك هو ", + "Ride Wallet": "محفظة الرحلة", + "Payment Method": "طريقة الدفع", + "Type here Place": "اكتب هنا المكان", + "Are You sure to ride to": "أنت متأكد إنك عايز تروح", + "Confirm": "تأكيد", + "Back": "رجوع", + "You are Delete": "أنت على وشك الحذف", + "Deleted": "تم الحذف", + "You Dont Have Any places yet !": "لسا معندكش أي أماكن!", + "Favorite Places": "الأماكن المفضلة", + "From : Current Location": "من: الموقع الحالي", + "Where to": "إلى أين", + "Profile": "الملف الشخصي", + "Home": "الصفحة الرئيسية", + "My Cared": "بطاقاتي", + "Add Card": "إضافة بطاقة", + "Add Credit Card": "إضافة بطاقة ائتمان", + "Please enter the cardholder name": "يرجى إدخال اسم حامل البطاقة", + "Please enter the expiry date": "يرجى إدخال تاريخ انتهاء الصلاحية", + "Please enter the CVV code": "يرجى إدخال رمز CVV", + "Go To Favorite Places": "الذهاب إلى الأماكن المفضلة", + "Go to this Target": "الذهاب إلى هذا الهدف", + "My Profile": "ملفي الشخصي", + "Sign Out": "تسجيل الخروج", + "Are you want to go to this site": "هل ترغب في الذهاب إلى هذا الموقع", + "MyLocation": "موقعي", + "my location": "موقعي", + "Target": "هدف", "By selecting 'I Agree' below, I have reviewed and agree to the Terms of Use and acknowledge the Privacy Notice. I am at least 18 years of age.": - "بِتَحْدِيد 'أُوَافِق' أَدْنَاهُ ، فَإِنَّنِي أُوَافِق عَلَى مُرَاجَعَة وَقَبُول شُرُوط الاسْتِخْدَام وَإِقْرَار إِشْعَار الخُصُوصِيَّة. أَنَا عَلَى الأَقَل 18 عَامًا مِنْ العُمْر.", - "Update": "تَحْدِيث", - "You Should choose rate figure": "يَجِب عَلَيْكَ اخْتِيَار تَقْيِيم", - "Login Captin": "تَسْجِيل دُخُول الكَابْتِن", - "Register Captin": "تَسْجِيل كَابْتِن جَدِيد", - "Send Verfication Code": "أَرْسِل رَمْز التَّحَقُّق", + "باختيار 'أوافق' أدناه، أكون قد راجعت ووافقت على شروط الاستخدام وأقر بإشعار الخصوصية. أنا على الأقل 18 سنة.", + "Update": "تحديث", + "You Should choose rate figure": "يجب عليك اختيار تقييم", + "Login Captin": "تسجيل دخول الكابتن", + "Register Captin": "تسجيل كابتن جديد", + "Send Verfication Code": "إرسال رمز التحقق", "KM": "كم", - "End Ride": "إنْهَاء الرِّحْلَة", - "Minute": "دَقِيقَة", - "Go to passenger Location now": "اذْهَب إِلَى مَوْقِع الرَّاكِب الآن", - "Duration of the Ride is ": "مُدَّة الرِّحْلَة هِيَ ", - "Distance of the Ride is ": "المَسَافَة لِلرِّحْلَة هِيَ", - "Name of the Passenger is ": "اسْم الرَّاكِب هُوَ", - "Hello this is Captain": "مَرْحَبًا هَذَا هُوَ الكَابْتِن", - "Start the Ride": "بَدْء الرِّحْلَة", + "End Ride": "إنهاء الرحلة", + "Minute": "دقيقة", + "Go to passenger Location now": "اذهب إلى موقع الراكب الآن", + "Duration of the Ride is ": "مدة الرحلة هي ", + "Distance of the Ride is ": "المسافة للرحلة هي", + "Name of the Passenger is ": "اسم الراكب هو", + "Hello this is Captain": "مرحباً، أنا الكابتن", + "Start the Ride": "بدء الرحلة", "Please Wait If passenger want To Cancel!": - "الرَّجَاء الانْتِظَار إِذَا أَرَادَ الرَّاكِب الإلْغَاء!", - "Total Duration:": "المُدَّة الإِجْمَالِيَّة:", - "Active Duration:": "المُدَّة الفَعَّالَة:", - "Waiting for Captin ...": "الانْتِظَار لِلْكَابْتِن ...", - "Age is ": "العُمْر هُوَ", - "Rating is ": "التَّقْيِيم هُوَ", - " to arrive you.": "لِلْوُصُول إِلَيْك.", - "Order History": "سِجِّل الطَّلَبَات", - "My Wallet": "مَحْفَظَتِي", - "Tariff": "تَعْرِيفَة", - "Settings": "الإِعْدَادَات", - "Feed Back": "اقْتِرَاحَات", - "Promos": "العُرُوض ", + "الرجاء الانتظار إذا أراد الراكب الإلغاء!", + "Total Duration:": "المدة الإجمالية:", + "Active Duration:": "المدة الفعلية:", + "Waiting for Captin ...": "في انتظار الكابتن...", + "Age is ": "العمر هو", + "Rating is ": "التقييم هو", + " to arrive you.": "للوصول إليك.", + "Order History": "سجل الطلبات", + "My Wallet": "محفظتي", + "Tariff": "تعريفة", + "Settings": "الإعدادات", + "Feed Back": "اقتراحات", + "Promos": "العروض", "Please enter a valid 16-digit card number": - "الرَّجَاء إِدْخَال رَقْم بَطَاقَة صَالِح مُكَوَّن مِنْ 16 رَقَمًا", - "Add Phone": "إضَافَة هَاتِف", - "Please enter a phone number": "الرَّجَاء إِدْخَال رَقْم هَاتِف", - "You dont Add Emergency Phone Yet!": - "لَمْ تَقُمْ بِإِضَافَة رَقْم هَاتِف طَوَارِئ بَعْد!", - "You will arrive to your destination after ": - "سَتَصِل إِلَى وَجْهَتِك بَعْد", - "You can cancel Ride now": "يُمْكِنُك إِلْغَاء الرِّحْلَة الآن", + "يرجى إدخال رقم بطاقة صالح مكون من 16 رقم", + "Add Phone": "إضافة هاتف", + "Please enter a phone number": "يرجى إدخال رقم هاتف", + "You dont Add Emergency Phone Yet!": "لسه مضفتش رقم هاتف طوارئ!", + "You will arrive to your destination after ": "هتوصل وجهتك بعد", + "You can cancel Ride now": "ممكن تلغي المشوار دلوقتي", "You Can cancel Ride After Captain did not come in the time": - "يُمْكِنُك إِلْغَاء الرِّحْلَة بَعْد أَنْ لَا يَأْتِي الكَابْتِن فِي الْوَقْت الْمُحَدَّد", + "ممكن تلغي المشوار بعد ما الكابتن ميوصلش في الوقت المحدد", "If you in Car Now. Press Start The Ride": - "إِذَا كُنْتَ فِي السَّيَّارَة الآن. اضْغَطْ عَلَى بَدْء الرِّحْلَة", - "You Dont Have Any amount in": "لَيْسَ لَدَيْكَ أَيُّ مَبْلَغ فِي", - "Wallet!": "الْمَحْفَظَة!", - "You Have": "لَدَيْك", - "Save Credit Card": "حِفْظ بَطَاقَة الائْتِمَان", - "Show Promos": "إِظْهَار الْعُرُوض التَّرْوِيجِيَّة", - "10 and get 4% discount": "10 وَاحْصُل عَلَى خَصْم 4%", - "20 and get 6% discount": "20 وَاحْصُل عَلَى خَصْم 6%", - "40 and get 8% discount": "40 وَاحْصُل عَلَى خَصْم 8%", - "100 and get 11% discount": "100 وَاحْصُل عَلَى خَصْم 11%", - "Pay with Your PayPal": "ادْفَعْ بِاسْتِخْدَام PayPal", - "You will choose one of above !": - "سَوْف تَخْتَار وَاحِدَة مِنْ أَعْلَاه!", - "Cancel": "إِلْغَاء", - "Delete My Account": "حَذْف حِسَابِي", - "Edit Profile": "تَعْدِيل الْمِلَف الشَّخْصِي", - "Name": "الاسْم", - // "Gender": "الْجِنْس", - "Update Gender": "تَحْدِيث الْجِنْس", - "Education": "التَّعْلِيم", - "Update Education": "تَحْدِيث التَّعْلِيم", - "Employment Type": "نَوْع التَّوْظِيف", - // "Marital Status": "الْحَالَة الاجْتِمَاعِيَّة", - "SOS Phone": "هَاتِف الطَّوَارِئ", - "High School Diploma": "شَهَادَة الثَّانَوِيَّة الْعَامَّة", - "Associate Degree": "دَرَجَة الزَّمَالَة", - "Bachelor's Degree": "بَكَالُورِيُوس", - "Master's Degree": "مَاجِسْتِير", - "Doctoral Degree": "دُكْتُورَاه", - + "لو أنت في العربية دلوقتي. اضغط على بدء الرحلة", + "You Dont Have Any amount in": "معندكش أي مبلغ في", + "Wallet!": "المحفظة!", + "You Have": "لديك", + "Save Credit Card": "حفظ بطاقة الائتمان", + "Show Promos": "إظهار العروض الترويجية", + "10 and get 4% discount": "10 واحصل على خصم 4%", + "20 and get 6% discount": "20 واحصل على خصم 6%", + "40 and get 8% discount": "40 واحصل على خصم 8%", + "100 and get 11% discount": "100 واحصل على خصم 11%", + "Pay with Your PayPal": "ادفع باستخدام PayPal", + "You will choose one of above !": "هتختار واحدة من اللي فوق!", + "Cancel": "إلغاء", + "Delete My Account": "حذف حسابي", + "Edit Profile": "تعديل الملف الشخصي", + "Name": "الاسم", + "Update Gender": "تحديث الجنس", + "Education": "التعليم", + "Update Education": "تحديث التعليم", + "Employment Type": "نوع التوظيف", + "SOS Phone": "هاتف الطوارئ", + "High School Diploma": "شهادة الثانوية العامة", + "Associate Degree": "درجة الدبلوم", + "Bachelor's Degree": "بكالوريوس", + "Master's Degree": "ماجستير", + "Doctoral Degree": "دكتوراه", "Copy this Promo to use it in your Ride!": - "انْسَخْ هَذَا الْعَرْض لِاسْتِخْدَامِهِ فِي رِحْلَتِك!", - "To change some Settings": "لِتَغْيِير بَعْض الإِعْدَادَات", - - "Order Request Page": "صَفْحَة طَلَب الطَّلَب", - "Rouats of Trip": "طُرُق الرِّحْلَة", - "Passenger Name is ": "اسْم الرَّاكِب هُوَ ", - "Total From Passenger is ": - "الْمَبْلَغ الإِجْمَالِي مِنَ الرَّاكِب هُوَ ", - "Duration To Passenger is ": "الْمُدَّة إِلَى الرَّاكِب هِيَ ", - "Distance To Passenger is ": "الْمَسَافَة إِلَى الرَّاكِب هِيَ ", - "Total For You is ": "الْمَبْلَغ الإِجْمَالِي لَك هُوَ ", - "Distance is ": "الْمَسَافَة هِيَ ", - " KM": " كِيلُومِتْر", - "Duration of Trip is ": "مُدَّة الرِّحْلَة هِيَ ", - " Minutes": " دَقَائِق", - "Apply Order": "قَبُول الطَّلَب", - "Refuse Order": "رَفْض الطَّلَب", - "Rate Captain": "تَقْيِيم الْكَابْتِن", - "Enter your Note": "أَدْخِل مُلَاحَظَتَك", - "Type something...": "اكْتُبْ شَيْئًا مَا...", - "Submit rating": "إِرْسَال التَّقْيِيم", - "Rate Passenger": "تَقْيِيم الرَّاكِب", - "Ride Summary": "مُلَخَّص الرِّحْلَة", - "welcome_message": "مَرْحَبًا بِك فِي سَفَر!", + "انسخ العرض ده علشان تستخدمه في مشوارك!", + "To change some Settings": "لتغيير بعض الإعدادات", + "Order Request Page": "صفحة طلب الطلب", + "Rouats of Trip": "طرق الرحلة", + "Passenger Name is ": "اسم الراكب هو ", + "Total From Passenger is ": "المبلغ الإجمالي من الراكب هو ", + "Duration To Passenger is ": "المدة للوصول للراكب هي ", + "Distance To Passenger is ": "المسافة للوصول للراكب هي ", + "Total For You is ": "المبلغ الإجمالي ليك هو ", + "Distance is ": "المسافة هي ", + " KM": " كيلومتر", + "Duration of Trip is ": "مدة الرحلة هي ", + " Minutes": " دقائق", + "Apply Order": "قبول الطلب", + "Refuse Order": "رفض الطلب", + "Rate Captain": "تقييم الكابتن", + "Enter your Note": "أدخل ملاحظتك", + "Type something...": "اكتب حاجة...", + "Submit rating": "إرسال التقييم", + "Rate Passenger": "تقييم الراكب", + "Ride Summary": "ملخص الرحلة", + "welcome_message": "مرحباً بك في سفر!", "app_description": - "سَفَر هُوَ تَطْبِيق تَطْبِيقَات مُشَارَكَة الرُّكُوب الآمِن وَالْمَوْثُوق وَيُمْكِن الْوُصُول إِلَيْهِ.", - "get_to_destination": "اذْهَبْ إِلَى وَجْهَتِك بِسُرْعَة وَسُهُولَة.", - "get_a_ride": - "مَع سَفَر، يُمْكِنُك الْحُصُول عَلَى رِحْلَة إِلَى وَجْهَتِك فِي دَقَائِق.", - "safe_and_comfortable": "اسْتَمْتِعْ بِرِحْلَة آمِنَة وَمُرِيحَة.", + "سفر هو تطبيق موثوق وآمن وسهل الوصول إليه لمشاركة الركوب.", + "get_to_destination": "اذهب إلى وجهتك بسرعة وسهولة.", + "get_a_ride": "مع سفر، تقدر تحصل على رحلة لوجهتك في دقايق.", + "safe_and_comfortable": "استمتع برحلة آمنة ومريحة.", "committed_to_safety": - "تَلْتَزِم سَفَر بِالسَّلَامَة، وَيَتِمُّ فَحْص جَمِيع قَبَاطِنِنَا بِعِنَايَة وَفَحْص خَلْفِيَّتِهِم.", - "Driver Applied the Ride for You": "طَلَبَ السَّائِق الرِّحْلَة لَك", - "Show latest promo": "أَظْهِر آخِر عَرْض تَرْوِيجِي", + "سفر ملتزمة بالسلامة، وكل الكباتن عندنا بيتفحصوا كويس ويتعملهم فحص خلفية.", + "Driver Applied the Ride for You": "السواق طلب المشوار ليك", + "Show latest promo": "أظهر آخر عرض ترويجي", "Cancel Trip": "إلغاء الرحلة", - "Passenger Cancel Trip": "الرَّاكِب أَلْغَى الرِّحْلَة", + "Passenger Cancel Trip": "الراكب ألغى الرحلة", "Please stay on the picked point.": - "الرَّجَاء الْبَقَاء فِي النُّقْطَة الْمُحَدَّدَة.", - "Trip is Begin": "بَدَأَت الرِّحْلَة", - "Hi ,I will go now": "مَرْحَبًا، سَأَذْهَب الآن", - "Passenger come to you": "الرَّاكِب فِي طَرِيقِهِ إِلَيْك", - "Hi ,I Arrive your site": "مَرْحَبًا، وَصَلْت مَكَانَك", - "Driver Finish Trip": "السَّائِق أَنْهَى الرِّحْلَة", - "you will pay to Driver": "سَتَدْفَع لِلسَّائِق", - "Driver Cancel Your Trip": "السَّائِق أَلْغَى رِحْلَتَك", + "الرجاء البقاء في النقطة المحددة.", + "Trip is Begin": "بدأت الرحلة", + "Driver is waiting at pickup.": + "السائق في انتظارك عند نقطة الاستلام.", + "Driver is on the way": "السائق في الطريق", + "Contact Options": "خيارات الاتصال", + "Send a custom message": "أرسل رسالة مخصصة", + "Type your message": "اكتب رسالتك", + "Hi ,I will go now": "مرحباً، أنا هتحرك دلوقتي", + "Passenger come to you": "الراكب جاي لك", + "Hi ,I Arrive your site": "مرحباً، وصلت مكانك", + "Driver Finish Trip": "السواق أنهى الرحلة", + "you will pay to Driver": "هتدفع للسواق", + "Driver Cancel Your Trip": "السواق ألغى رحلتك", "you will pay to Driver you will be pay the cost of driver time look to your SEFER Wallet": - "سَتَدْفَع لِلسَّائِق تَكْلِفَة وَقْتِهِ تَفَقَّدْ مَحْفَظَتَك فِي سَفَر", - "I will go now": "سَأَذْهَب الآن", - "You Have Tips": "لَدَيْك زِيَادَة مَال", - " tips\nTotal is": "زِيَادَة مَال\nالْمَجْمُوع هُوَ", - "No,I want": "لَا، أُرِيد", - "Your fee is ": "أَجْرُك هُوَ", + "هتدفع للسواق تكلفة وقته، بص على محفظتك في سفر", + "I will go now": "أنا هتحرك دلوقتي", + "You Have Tips": "عندك زيادة فلوس", + " tips\nTotal is": " زيادة مال\nالمجموع هو", + "No,I want": "لأ، أنا عايز", + "Your fee is ": "الأجرة بتاعتك هي ", "Do you want to pay Tips for this Driver": - "هَل تُرِيد دَفْع أُكْرَامِيَّة لِهَذَا السَّائِق؟", - "Tip is ": " مَبْلَغ الأُكْرَامِيَّة هُوَ", + "هل تريد دفع بقشيش للسواق ده؟", + "Tip is ": " مبلغ البقشيش هو", "Are you sure to delete this location?": - "هل أنت متأكد من حذف هذا الموقع؟", - 'Are you want to wait drivers to accept your order': - 'هل تريد الانتظار حتى يقبل السائقون طلبك؟', - + "أنت متأكد إنك عايز تحذف المكان ده؟", + "Are you want to wait drivers to accept your order": + "هل عايز تستنى لحد ما السواقين يقبلوا طلبك؟", "deleted": "تم الحذف", - 'Trip is begin': "الرحلة قد بدأت", - 'This price is fixed even if the route changes for the driver.': - "هذا السعر مثبت حتى لو تغير المسار للسائق", - 'The price may increase if the route changes.': + "Trip is begin": "الرحلة بدأت", + "This price is fixed even if the route changes for the driver.": + "السعر ده ثابت حتى لو المسار اتغير للسواق.", + "The price may increase if the route changes.": "احتمالية زيادة السعر عند تغيير المسار", "The captain is responsible for the route.": "الكابتن مسؤول عن المسار", - 'Your order is being prepared': "جاري تجهيز الطلب", - 'The drivers are reviewing your request': 'يدرس السائقين طلبك', - 'Your order sent to drivers': 'تم إرسال طلبك إلى السائقين', - "يمكنك الاتصال أو تسجيل صوت لهذه الرحلة": - "You can call or record audio of this trip", - - 'The trip has started! Feel free to contact emergency numbers, share your trip, or activate voice recording for the journey': - "بدأت الرحلة! لا تتردد في الاتصال بأرقام الطوارئ، مشاركة رحلتك، أو تفعيل التسجيل الصوتي للرحلة", - 'Please make sure you have all your personal belongings and that any remaining fare, if applicable, has been added to your wallet before leaving. Thank you for choosing the Sefer app': - 'الرجاء التأكد من جميع أغراضك الشخصية وأنه تم إضافة باقي الأجرة إن وجد إلى محفظتك قبل النزول. شكرا لاختيارك تطبيق سفر', - 'Don’t forget your personal belongings.': "لا تنسى متعلقاتك الشخصية", - "Tip is": " مَبْلَغ الأُكْرَامِيَّة هُوَ", - "Camera Access Denied.": "تَمَّ رَفْض الْوُصُول إِلَى الْكَامِيرَا.", - "Open Settings": "افْتَحْ الإِعْدَادَات", - "GPS Required Allow !.": "تَمْكِين الـ GPS مَطْلُوب!", - "Your Account is Deleted": "تَمَّ حَذْف حِسَابِك", + "We are search for nearst driver": "بندور على أقرب سواق", + "Your order is being prepared": "جاري تجهيز الطلب", + "The drivers are reviewing your request": "السواقين بيدرسوا طلبك", + "Your order sent to drivers": "تم إرسال طلبك للسواقين", + "You can call or record audio of this trip": + "ممكن تتصل أو تسجل صوت للرحلة دي", + "The trip has started! Feel free to contact emergency numbers, share your trip, or activate voice recording for the journey": + "بدأت الرحلة! براحتك تتصل بأرقام الطوارئ، تشارك رحلتك، أو تفعل التسجيل الصوتي للرحلة", + "Please make sure you have all your personal belongings and that any remaining fare, if applicable, has been added to your wallet before leaving. Thank you for choosing the Sefer app": + "الرجاء التأكد من جميع أغراضك الشخصية وإضافة باقي الأجرة في محفظتك قبل النزول. شكراً لاختيارك تطبيق سفر", + "Don’t forget your personal belongings.": "متنساش متعلقاتك الشخصية.", + "Camera Access Denied.": "تم رفض الوصول للكاميرا.", + "Open Settings": "افتح الإعدادات", + "GPS Required Allow !.": "تفعيل GPS مطلوب!", + "Your Account is Deleted": "تم حذف حسابك", "Are you sure to delete your account?": - "هَل أَنْت مُتَأَكِّد مِن حَذْف حِسَابِك؟", + "أنت متأكد إنك عايز تحذف حسابك؟", "Your data will be erased after 2 weeks\nAnd you will can't return to use app after 1 month ": - "سَيَتِمُّ مَسْح بِيَانَاتِك بَعْد أُسْبُوعَيْن\nوَلَن تَسْتَطِيع اسْتِخْدَام التَّطْبِيق مَرَّة أُخْرَى بَعْد شَهْر", - "Enter Your First Name": "أَدْخِل اسْمَك الأَوَّل", - "Are you Sure to LogOut?": - "هَل أَنْت مُتَأَكِّد مِن تَسْجِيل الْخُرُوج؟", - "Email Wrong": "الْبَرِيد الإِلَكْتْرُونِي خَاطِئ", - "Email you inserted is Wrong.": - "الْبَرِيد الإِلَكْتْرُونِي الَّذِي أَدْخَلْتَه خَطَأ.", - "You have finished all times ": - "لَقَد اسْتَنْفَذْت كُلَّ الْمُحَاوَلَات ", + "بياناتك هتتمسح بعد أسبوعين\nومش هتقدر ترجع تستخدم التطبيق تاني بعد شهر", + "Enter Your First Name": "أدخل اسمك الأول", + "Are you Sure to LogOut?": "أنت متأكد إنك عايز تسجل الخروج؟", + "Email Wrong": "البريد الإلكتروني غلط", + "Email you inserted is Wrong.": "البريد الإلكتروني اللي أدخلته غلط.", + "You have finished all times ": "لقد استنفدت كل المحاولات", "if you want help you can email us here": - "إِذَا كُنْت تُرِيد الْمُسَاعَدَة يُمْكِنُك إِرْسَال بَرِيد إِلَكْتْرُونِي إِلَيْنَا هُنَا", - "Thanks": "شُكْرًا", - "Email Us": "أَرْسِل لَنَا بَرِيد إِلَكْتْرُونِي", + "لو عايز مساعدة ممكن تبعتلنا إيميل هنا", + "Thanks": "شكراً", + "Email Us": "ابعت لنا إيميل", "I cant register in your app in face detection ": - "لَا أَسْتَطِيع التَّسْجِيل فِي تَطْبِيقِكُم بِسَبَب الْكَشْف عَن الْوَجْه", - "Hi": "مَرْحَبَا", - "No face detected": "لَمْ يَتِمَّ الْكَشْف عَن أَيِّ وَجْه", - "Image detecting result is ": "نَتِيجَة الْكَشْف عَن الصُّورَة هِيَ", - "from 3 times Take Attention": "مِن 3 مُحَاوَلَات انْتَبِه", + "مش عارف أسجل في تطبيقكم بسبب كشف الوجه", + "Hi": "مرحباً", + "No face detected": "لم يتم الكشف عن أي وجه", + "Image detecting result is ": "نتيجة الكشف عن الصورة هي", + "from 3 times Take Attention": "من 3 محاولات انتبه", "Be sure for take accurate images please\nYou have": - "الرَّجَاء التَّأَكُّد مِن الْتِقَاط صُوَر دَقِيقَة\nلَدَيْك", - "image verified": "الصُّورَة مُوَثَّقَة", - "Next": "التَّالِي", - "There is no help Question here": "لَا تُوجَد أَسْئِلَة هُنَا", - "Call End": "انْتِهَاء الْمُكَالَمَة", - "You dont have Points": "لَيْس لَدَيْك نِقَاط", - "You Are Stopped For this Day !": - "تَمَّ تَوْقِيفُك لِهَذَا الْيَوْم!", - "You must be charge your Account": - "يَجِب إِعَادَة شَحْن رَصِيد النِّقَاط", + "الرجاء التأكد من التقاط صور دقيقة\nلديك", + "image verified": "الصورة موثقة", + "Next": "التالي", + "There is no help Question here": "مفيش أسئلة مساعدة هنا", + "Call End": "انتهاء المكالمة", + "You dont have Points": "معندكش نقاط", + "You Are Stopped For this Day !": "تم توقيفك لهذا اليوم!", + "You must be charge your Account": "يجب إعادة شحن رصيد النقاط", "You Refused 3 Rides this Day that is the reason \nSee you Tomorrow!": - "رَفَضْت 3 رِحَلَات هَذَا الْيَوْم وَهَذَا السَّبَب\nلِقَائِنَا غَدًا!", - "Recharge my Account": "ادْفَع رُسُوم مِن حِسَابِي", - "Ok , See you Tomorrow": "حَسَنًا، لِقَائِنَا غَدًا", - "You are Stopped": "تَمَّ تَوْقِيفُك", - "Connected": "مُتَّصِل", - "Not Connected": "غَيْر مُتَّصِل", - "Your are far from passenger location": - "أَنْت بَعِيد عَن مَكَان الرَّاكِب", + "رفضت 3 رحلات النهاردة وده السبب\nنتقابل بكرة!", + "Recharge my Account": "ادفع رسوم من حسابي", + "Ok , See you Tomorrow": "تمام، نتقابل بكرة", + "You are Stopped": "تم توقيفك", + "Connected": "متصل", + "Not Connected": "غير متصل", + "Your are far from passenger location": "أنت بعيد عن مكان الراكب", "go to your passenger location before\nPassenger cancel trip": - "اذْهَب إِلَى مَكَان الرَّاكِب قَبْل أَن\nيُلْغِي الرَّاكِب الرِّحْلَة", + "اذهب إلى مكان الراكب قبل أن\nيلغي الراكب الرحلة", "You will get cost of your work for this trip": - "سَتَحْصُل عَلَى تَكَالِيف عَمَلِك لِهَذِهِ الرِّحْلَة", - " in your wallet": "فِي مَحْفَظَتِك", - "you gain": "رَبِحْت", - "Order Cancelled": "تَمَّ إِلْغَاء الطَّلَب", - "Order Cancelled by Passenger": - "تَمَّ إِلْغَاء الطَّلَب مِن قِبَل الرَّاكِب", - "Success": "نَجَاح", - "Feedback data saved successfully": - "تَمَّ حِفْظ بَيَانَات التَّعْلِيقَات بِنَجَاح", - "No Promo for today .": "لَا يُوجَد عَرْض تَرْوِيجِي الْيَوْم.", - "Select your destination": "اخْتَر وَجْهَتَك", - "Search for your Start point": "بَحْث عَن نُقْطَة الانْطِلَاق", - "Search for waypoint": "بَحْث عَن النُّقْطَة الآلِيَّة", - "Current Location": "الْمَوْقِع الْحَالِي", - "Add Location 1": "إِضَافَة الْمَوْقِع 1", - "You must Verify email !.": - "يَجِب التَّحَقُّق مِن الْبَرِيد الإِلَكْتْرُونِي!", - "Cropper": "الْقَاصَّة", - "Saved Sucssefully": "تَمَّ الْحِفْظ بِنَجَاح", - "Select Date": "اخْتَر التَّارِيخ", - "Birth Date": "تَارِيخ الْمِيلَاد", - "Ok": "مُوَافِق", - "the 500 points equal 30 JOD": - "النِّقَاط الـ 500 تُسَاوِي 30 دِينَار أُرْدُنِي", + "هتحصل على تكاليف عملك لهذه الرحلة", + " in your wallet": "في محفظتك", + "you gain": "ربحت", + "Order Cancelled": "تم إلغاء الطلب", + "Order Cancelled by Passenger": "تم إلغاء الطلب من قبل الراكب", + "Success": "نجاح", + "Feedback data saved successfully": "تم حفظ بيانات التعليقات بنجاح", + "No Promo for today .": "مفيش عروض ترويجية النهاردة.", + "Select your destination": "اختار وجهتك", + "Search for your Start point": "ابحث عن نقطة الانطلاق", + "Search for waypoint": "ابحث عن النقطة الآلية", + "Current Location": "الموقع الحالي", + "Add Location 1": "إضافة الموقع 1", + "You must Verify email !.": "يجب التحقق من البريد الإلكتروني!", + "Cropper": "القاصة", + "Saved Sucssefully": "تم الحفظ بنجاح", + "Select Date": "اختر التاريخ", + "Birth Date": "تاريخ الميلاد", + "Ok": "موافق", + "the 500 points equal 30 JOD": "الـ 500 نقطة تساوي 30 دينار أردني", "the 500 points equal 30 JOD for you \nSo go and gain your money": - "النِّقَاط الـ 500 تُسَاوِي 30 دِينَار أُرْدُنِي\nفَاسْتَحِقَّ فُلُوسَك وَاكْسِب النِّقَاط", - "token updated": "تَمَّ تَحْدِيث الرَّمْز", - "Add Location 2": "إِضَافَة الْمَوْقِع 2", - "Add Location 3": "إِضَافَة الْمَوْقِع 3", - "Add Location 4": "إِضَافَة الْمَوْقِع 4", - "Waiting for your location": "فِي انْتِظَار مَوْقِعِك", - "Search for your destination": "بَحْث عَن وَجْهَتِك", - "Hi! This is": "مَرْحَبَا! هَذَا", - " I am using": "أَنَا أَسْتَخْدِم", - " to ride with": "لِلرُّكُوب مَع", - " as the driver.": "كَسَائِق.", - "is driving a ": "يَقُود", - " with license plate ": "بِلَوْحَة تَرْخِيص", - " I am currently located at ": "أَنَا حَالِيًّا فِي", - "Please go to Car now ": - 'الرَّجَاء التَّحَرُّك إِلَى السَّيَّارَة الآن', - 'You will receive a code in WhatsApp Messenger': + "الـ 500 نقطة تساوي 30 دينار أردني\nفاستحق فلوسك واكسب النقاط", + "token updated": "تم تحديث الرمز", + "Add Location 2": "إضافة الموقع 2", + "Add Location 3": "إضافة الموقع 3", + "Add Location 4": "إضافة الموقع 4", + "Waiting for your location": "في انتظار موقعك", + "Search for your destination": "ابحث عن وجهتك", + "Hi! This is": "مرحباً! أنا", + " I am using": " أنا بستخدم", + " to ride with": " للركوب مع", + " as the driver.": " كسائق.", + "is driving a ": "يقود", + " with license plate ": "بلوحة ترخيص", + " I am currently located at ": "أنا حالياً في", + "Please go to Car now ": "الرجاء التحرك إلى السيارة الآن", + "You will receive a code in WhatsApp Messenger": "سوف تتلقى رمزًا في واتساب ماسنجر", - 'If you need assistance, contact us': + "If you need assistance, contact us": "إذا كنت بحاجة إلى المساعدة، تواصل معنا", "Promo Ended": "انتهى العرض", - 'Enter the promo code and get': 'أدخل رمز الترويج واحصل على', - 'DISCOUNT': 'خصم', - 'No wallet record found': 'لم يتم العثور على سجل محفظة', - 'for': 'لمدة', + "Enter the promo code and get": "أدخل رمز الترويج واحصل على", + "DISCOUNT": "خصم", + "No wallet record found": "لم يتم العثور على سجل محفظة", + "for": "لمدة", "SEFER is the safest ride-sharing app that introduces many features for both captains and passengers. We offer the lowest commission rate of just 8%, ensuring you get the best value for your rides. Our app includes insurance for the best captains, regular maintenance of cars with top engineers, and on-road services to ensure a respectful and high-quality experience for all users.": - "سفر هو التطبيق الأكثر أمانًا لمشاركة الركوب الذي يقدم العديد من الميزات لكل من السائقين والركاب. نحن نقدم أقل عمولة بنسبة 8% فقط، مما يضمن حصولك على أفضل قيمة لرحلاتك. يتضمن تطبيقنا التأمين لأفضل السائقين، الصيانة المنتظمة للسيارات مع أفضل المهندسين، والخدمات على الطريق لضمان تجربة محترمة وعالية الجودة لجميع المستخدمين.", + "سفر هو أكتر تطبيق آمن لمشاركة الركوب وبيقدّم مميزات كتير للكباتن والركاب. إحنا بنقدّم أقل نسبة عمولة وهي 8% بس، وده بيضمن إنك تاخد أحسن قيمة لمشاويرك. تطبيقنا فيه تأمين لأحسن الكباتن، صيانة دورية للعربيات مع أحسن المهندسين، وخدمات على الطريق لضمان تجربة محترمة وعالية الجودة لكل المستخدمين.", "You can contact us during working hours from 12:00 - 19:00.": - "يمكنك الاتصال بنا خلال ساعات العمل من 12:00 - 7:00.", + "ممكن تتصل بينا في مواعيد العمل من الساعة 12:00 للساعة 7:00 مساءً.", "Contact Us": "اتصل بنا", - 'Choose a contact option': 'اختر خيار الاتصال', - 'Work time is from 12:00 - 19:00.\nYou can send a WhatsApp message or email.': - 'ساعات العمل من 12:00 - 19:00.\nيمكنك إرسال رسالة عبر واتساب أو بريد إلكتروني.', - 'Promo code copied to clipboard!': "'تم نسخ رمز العرض إلى الحافظة!'", - 'Copy Code': 'نسخ الرمز', + "Choose a contact option": "اختر طريقة الاتصال", + "Work time is from 12:00 - 19:00.\nYou can send a WhatsApp message or email.": + "مواعيد العمل من الساعة 12:00 للساعة 7:00 مساءً.\nممكن تبعت رسالة واتساب أو إيميل.", + "Promo code copied to clipboard!": "تم نسخ رمز العرض إلى الحافظة!", + "Copy Code": "نسخ الرمز", "Your invite code was successfully applied!": "تم تطبيق رمز الدعوة بنجاح!", - "Payment Options": " خيارات الدفع", + "Payment Options": "خيارات الدفع", "wait 1 minute to receive message": - "انتظر دقيقة واحدة لاستلام الرسالة", - 'Promo Copied!': 'تم نسخ العرض!', - 'You have copied the promo code.': 'لقد قمت بنسخ رمز العرض.', - 'Valid Until:': 'لمدة:', - "Select Payment Amount": " اختر مبلغ الدفع", + "استنى دقيقة واحدة لاستلام الرسالة", + "Promo Copied!": "تم نسخ العرض!", + "You have copied the promo code.": "تم نسخ رمز العرض.", + "Valid Until:": "صالح حتى:", + "Select Payment Amount": "اختر مبلغ الدفع", "The promotion period has ended.": "انتهت فترة العرض.", "Promo Code Accepted": "تم قبول كود العرض", - 'Tap on the promo code to copy it!': 'اضغط على رمز العرض لنسخه!', - "Lowest Price Achieved": "تم الوصول إلى أدنى سعر", + "Tap on the promo code to copy it!": "اضغط على رمز العرض لنسخه!", + "Lowest Price Achieved": "تم الوصول إلى أقل سعر", "Cannot apply further discounts.": "لا يمكن تطبيق المزيد من الخصومات.", "Promo Already Used": "تم استخدام كود العرض بالفعل", - 'Invitation Used': "تم استخدام الدعوة", + "Invitation Used": "تم استخدام الدعوة", "You have already used this promo code.": "لقد استخدمت هذا الكود بالفعل.", "Insert Your Promo Code": "أدخل كود العرض الخاص بك", "Enter promo code here": "أدخل كود العرض هنا", "Please enter a valid promo code": "يرجى إدخال كود عرض صالح", - 'Awfar Car': 'أوفر كار', + "Awfar Car": "أوفر كار", "Old and affordable, perfect for budget rides.": - "سيارة ميسورة التكلفة، مثالية للرحلات الاقتصادية.", + "سيارة قديمة وبسعر معقول، مثالية للمشاوير الاقتصادية.", " If you need to reach me, please contact the driver directly at": - "إِذَا كُنْت تَحْتَاج إِلَى التَّوَاصُل مَعِي، يُرْجَى التَّوَاصُل مَع السَّائِق مُبَاشَرَةً عَلَى", + "لو محتاج تتواصل معايا، يرجى التواصل مع السواق مباشرة على", "No Car or Driver Found in your area.": - "لَمْ يَتِمَّ الْعَثُور عَلَى سَيَّارَة أَو سَائِق فِي مِنْطَقَتِك.", - "Please Try anther time ": "الرَّجَاء إِعَادَة الْمُحَاوَلَة", + "لم يتم العثور على سيارة أو سواق في منطقتك.", + "Please Try anther time ": "الرجاء المحاولة في وقت آخر", "There no Driver Aplly your order sorry for that ": - "لَا يُوجَد سَائِق قَبِل طَلَبِك، نَعْتَذِر عَن ذَلِك", - "Trip Cancelled": "تَمَّ إِلْغَاء الرِّحْلَة", + "مفيش سواق قبل طلبك، آسفين على كده", + "Trip Cancelled": "تم إلغاء الرحلة", "The Driver Will be in your location soon .": - "سَيَكُون السَّائِق قَرِيبًا فِي مَوْقِعِك.", - "The distance less than 500 meter.": - "الْمَسَافَة أَقَلُّ مِن 500 مِتْر.", - "Promo End !": "انْتِهَاء الْعَرَض!", - "There is no notification yet": "لَا تُوجَد إِشْعَارَات بَعْد", + "السواق هيكون في موقعك قريبًا.", + "The distance less than 500 meter.": "المسافة أقل من 500 متر.", + "Promo End !": "انتهاء العرض!", + "There is no notification yet": "لا توجد إشعارات بعد", "Use Touch ID or Face ID to confirm payment": - "اسْتَخْدِم Touch ID أَو Face ID لِتَأْكِيد الدَّفْع", + "استخدم Touch ID أو Face ID لتأكيد الدفع", "Contact us for any questions on your order.": - "تَوَاصَل مَعَنَا لِأَيِّ اسْتِفْسَارَات حَوْل طَلَبِك.", - "Pyament Cancelled .": "تَمَّ إِلْغَاء الدَّفْع.", - "type here": "اُكْتُب هُنَا", - "Scan Driver License": "اسْتِخْرَاج رُخْصَة الْقِيَادَة", + "تواصل معانا لو عندك أي استفسارات بخصوص طلبك.", + "Pyament Cancelled .": "تم إلغاء الدفع.", + "type here": "اكتب هنا", + "Scan Driver License": "مسح رخصة القيادة", "Please put your licence in these border": - "الرَّجَاء وَضْع رُخْصَتِك ضِمْن هَذَا الْحُدُود", - "Camera not initialized yet": "الْكَامِيرَا لَمْ تُثَبَّت بَعْد", - "Take Image": "إِلْتَقَاط الصُّورَة", - "AI Page": "صَفْحَة الذَّكَاء الاِصْطِنَاعِي", - "Take Picture Of ID Card": "إِلْتَقَاط صُورَة لِبَطَاقَة الْهُوِّيَة", + "الرجاء وضع رخصتك داخل هذا الإطار", + "Camera not initialized yet": "الكاميرا لم يتم تشغيلها بعد", + "Take Image": "التقاط الصورة", + "AI Page": "صفحة الذكاء الاصطناعي", + "Take Picture Of ID Card": "التقاط صورة لبطاقة الهوية", "Take Picture Of Driver License Card": - "إِلْتَقَاط صُورَة لِبَطَاقَة رُخْصَة الْقِيَادَة", + "التقاط صورة لبطاقة رخصة القيادة", "We are process picture please wait ": - "نَقُوم بِمَعَالَجَة الصُّورَة الرَّجَاء الإِنْتِظَار", - "There is no data yet.": "لَا تُوجَد بَيَانَات بَعْد.", - "Name :": "الاِسْم:", - "Drivers License Class: ": "فَئَة رُخْصَة الْقِيَادَة:", - "Document Number: ": "رَقْم الْمُسْتَنَد:", - "Address: ": "الْعُنْوَان:", - "Height: ": "الطُّول:", - "Expiry Date: ": "تَارِيخ الإِنْتِهَاء:", - "Date of Birth: ": "تَارِيخ الْمِيلَاد:", + "نقوم بمعالجة الصورة، الرجاء الانتظار", + "There is no data yet.": "لا توجد بيانات بعد.", + "Name :": "الاسم:", + "Drivers License Class: ": "فئة رخصة القيادة:", + "Document Number: ": "رقم المستند:", + "Address: ": "العنوان:", + "Height: ": "الطول:", + "Expiry Date: ": "تاريخ الانتهاء:", + "Date of Birth: ": "تاريخ الميلاد:", "You can\'t continue with us .\nYou should renew Driver license": - "لَا يُمْكِنُك الاِسْتِمْرَار مَعَنَا. يَجِب تَجْدِيد رُخْصَة الْقِيَادَة", - "Detect Your Face ": "الْكَشْف عَن وَجْهِك", + "لا يمكنك الاستمرار معانا. يجب تجديد رخصة القيادة", + "Detect Your Face ": "التعرف على وجهك", "Go to next step\nscan Car License.": - "اِذْهَب إِلَى الْخُطْوَة الْتَّالِيَة\naاسْتِخْرَاج رُخْصَة السَّيَّارَة.", - "Name in arabic": "الاِسْم بِاللُّغَة الْعَرَبِيَّة", - "Drivers License Class": "فَئَة رُخْصَة الْقِيَادَة", - - "Date of Birth": "تَارِيخ الْمِيلَاد", - 'Select date and time of trip': 'اختر تاريخ ووقت الرحلة', - 'Selected Date': 'التاريخ المحدد', - 'Select Time': 'اختر الوقت', - 'Selected Time': 'الوقت المحدد', - 'OK': 'موافق', - 'Cancel': 'إلغاء', - 'Selected Date and Time': "التاريخ والوقت المحددان", - "Lets check Car license ": - "دَعْنَا نَتَحَقَّق مِن رُخْصَة السَّيَّارَة ", - // 'Driver List': 'قائمة السائقين', - 'Car': 'السيارة', - 'Plate': 'لوحة السيارة', - 'N/A': 'غير متوفر', - 'Rides': 'الرحلات', - 'Age': 'العمر', - 'Education': 'التعليم', - 'Color': 'اللون', - 'Displacement': 'السعة', - 'Fuel': 'الوقود', - 'Selected driver': 'السائق المختار', - "Lets check License Back Face": - "دَعْنَا نَتَحَقَّق مِن الْوَجْه الْخَلْفِي لِلرُّخْصَة", - "Car License Card": "بَطَاقَة رُخْصَة السَّيَّارَة", - "No image selected yet": "لَمْ يَتِمَّ اخْتِيَار أَيُّ صُورَة بَعْد", - "Made :": "الصَّنَاعَة:", - "model :": "النَّوْع:", - "VIN :": "رَقْم الشَّاصِي:", - "year :": "السَّنَة:", - "ُExpire Date": 'تَارِيخ الانْتِهَاء', - "Login Driver": "تَسْجِيل دُخُول السَّائِق", + "اذهب للخطوة اللي بعدها\nوامسح رخصة العربية.", + "Name in arabic": "الاسم باللغة العربية", + "Drivers License Class": "فئة رخصة القيادة", + "Date of Birth": "تاريخ الميلاد", + "Select date and time of trip": "اختر تاريخ ووقت الرحلة", + "Selected Date": "التاريخ المحدد", + "Select Time": "اختر الوقت", + "Selected Time": "الوقت المحدد", + "OK": "موافق", + "Cancel": "إلغاء", + "Selected Date and Time": "التاريخ والوقت المحددين", + "Lets check Car license ": "يلا نفحص رخصة العربية", + "Car": "السيارة", + "Plate": "لوحة السيارة", + "N/A": "غير متوفر", + "Rides": "الرحلات", + "Age": "العمر", + "Education": "التعليم", + "Color": "اللون", + "Displacement": "السعة", + "Fuel": "الوقود", + "Selected driver": "السواق اللي اخترته", + "Lets check License Back Face": "يلا نفحص الوجه الخلفي للرخصة", + "Car License Card": "بطاقة رخصة السيارة", + "No image selected yet": "لم يتم اختيار أي صورة بعد", + "Made :": "الصنع:", + "model :": "الموديل:", + "VIN :": "رقم الشاسيه:", + "year :": "السنة:", + "ُExpire Date": "تاريخ الانتهاء", + "Login Driver": "تسجيل دخول السائق", "Password must br at least 6 character.": - "كَلِمَة الْمُرُور يَجِب أَنْ تَكُون عَلَى الأَقَلِّ 6 أَحْرُف.", - "if you don\'t have account": "إِذَا لَمْ يَكُن لَدَيْك حِسَاب", - 'Here recorded trips audio': 'قائمة تسجيلات الرحلات الصوتية', - "Register as Driver": "التَّسْجِيل كَسَائِق", - "Privacy Notice": "إِخْطَار الْخُصُوصِيَّة", + "كلمة المرور لازم تكون 6 حروف على الأقل.", + "if you don\'t have account": "لو معندكش حساب", + "Here recorded trips audio": "هنا تسجيلات صوتية للرحلات", + "Register as Driver": "التسجيل كسائق", + "Privacy Notice": "إخطار الخصوصية", 'By selecting "I Agree" below, I have reviewed and agree to the Terms of Use and acknowledge the ': - "بِاخْتِيَارِي' أُوَافِق' أَدْنَاه، قُمْت بِمُرَاجَعَة وَالْمُوَافَقَة عَلَى شُرُوط الاِسْتِخْدَام وَالاِعْتِرَاف بِـ", - ". I am at least 18 years of age.": - ". أَنَا بَالِغ عُمْرِي عَلَى الأَقَلِّ 18 سَنَة.", - "Log Out Page": "صَفْحَة تَسْجِيل الْخُرُوج", - "Log Off": "تَسْجِيل الْخُرُوج", - "Register Driver": "تَسْجِيل سَائِق جَدِيد", - "Verify Email For Driver": - "التَّحَقُّق مِن الْبَرِيد الإِلَكْتْرُونِي لِلسَّائِق", - "Admin DashBoard": "لَوْحَة تَحْكُم الْمُدِير", - "Your name": "إِسْمُك", - "your ride is applied": 'تَمَّ قَبُول الطَّلَب', - "Your password": "كَلِمَة الْمُرُور الْخَاصَّة بِك", - "H and": 'سَاعَه و', - "LE": 'جُنَيْه', - "JOD": 'دِينَار', - "m": 'دَقِيقَه', - "We search nearst Driver to you": - "بَنْبَحَث عَن أَقْرَب سَائِق لَيْك", + "باختياري 'أوافق' أدناه، قمت بمراجعة والموافقة على شروط الاستخدام والإقرار بـ", + ". I am at least 18 years of age.": ". أنا عمري 18 سنة على الأقل.", + "Log Out Page": "صفحة تسجيل الخروج", + "Log Off": "تسجيل الخروج", + "Register Driver": "تسجيل سائق جديد", + "Verify Email For Driver": "التحقق من البريد الإلكتروني للسائق", + "Admin DashBoard": "لوحة تحكم المدير", + "Your name": "اسمك", + "your ride is applied": "تم قبول الطلب بتاعك", + "Your password": "كلمة المرور بتاعتك", + "H and": "ساعة و", + "LE": "جنيه", + "JOD": "دينار", + "m": "دقيقة", + "We search nearst Driver to you": "بندور على أقرب سواق ليك", "please wait till driver accept your order": - "الرَّجَاء الاِنْتِظَار حَتَّى يَقْبَل السَّائِق طَلَبِك", + "الرجاء الانتظار لحد ما السواق يقبل طلبك", "No accepted orders? Try raising your trip fee to attract riders.": - "مَفِيش طَلَبَات مَقْبُولَة؟ حَاوِل رَفْع سَعْر الرِّحْلَة لِجَذْب الرُّكَّاب", - "You should select one": "يَجِب عَلَيْك اخْتِيَار وَاحِد", - "The driver accept your order for": - "قَبِل السَّائِق طَلَبِك بِمَبْلَغ", - "Increase Fee": "ارْفَع السَّعْر", - "No, thanks": "لَا شُكْرًا", - "The driver on your way": 'الْكَابِتِن فِي طَرِيقَه إِلَيْك', - "Total price from ": 'الْمَبْلَغ الْمَطْلُوب مِن ', - "Order Details Speed": 'طَلَب سَرِيع', - "Order Applied": "تَمَّ قَبُول الطَّلَب", - "accepted your order": 'قَبِل طَلَبِك', + "مفيش طلبات مقبولة؟ حاول تزود أجرة المشوار لجذب الركاب.", + "You should select one": "لازم تختار واحد", + "The driver accept your order for": "السواق قبل طلبك بمبلغ", + "Increase Fee": "زود الأجرة", + "No, thanks": "لا، شكرًا", + "The driver on your way": "الكابتن في طريقه إليك", + "Total price from ": "السعر الإجمالي من ", + "Order Details Speed": "طلب سريع", + "Order Applied": "تم قبول الطلب", + "accepted your order": "قبل طلبك", "We regret to inform you that another driver has accepted this order.": - 'نَأْسَف لإِبْلَاغِك بِأَنَّ سَائِقًا آَخَر قَد قَبِل هَذَا الطَّلَب', - "Selected file:": "الملفُّ المُخْتَارُ:", - "Your trip cost is": "تَبْلُغُ تَكْلِفَةُ رِحْلَتِكَ", + "نأسف لإبلاغك بأن سائق آخر قد قبل هذا الطلب", + "Selected file:": "الملف المختار:", + "Your trip cost is": "تكلفة رحلتك هي", "this will delete all files from your device": - "حَذْفُ هذا سيُؤدِّي إلى حَذْفِ جَميعِ المَلَفَّاتِ مِنْ جِهَازِكَ", - "you have a negative balance of": - "وَلَكِنْ لَدَيْكَ رَصِيدٌ سَلْبِيٌّ قَدْرُهُ", - " in your": "فِي مَحْفَظَتِكَ", + "حذف هذا سيمسح كل الملفات من جهازك", + "you have a negative balance of": "عندك رصيد سالب بقيمة", + " in your": "في محفظتك", "Exclusive offers and discounts always with the Sefer app": - "عُرُوضٌ حَصْرِيَّةٌ وَتَخْفِيضَاتٌ دَائِمَةٌ مَعَ تَطْبِيقِ سَفَرَ", - "Please go to Car Driver": "تَوَجَّهْ إِلَى سَائِقِ السَّيَّارَةِ", - " wallet due to a previous trip.": 'بِسَبَبِ رِحْلَةٍ سَابِقَةٍ', - "Submit Question": "طَرْحُ السُّؤَالِ", - "Please enter your Question.": "الرَّجَاءُ إِدْخَالُ سُؤَالِكَ.", - "Help Details": "تَفَاصِيلُ المُسَاعَدَةِ", - "No trip yet found": 'لَمْ يَتِمَّ حَجْزُ أَيِّ رِحْلَةٍ بَعْدُ ', - "No Response yet.": "لَا يُوجَدُ رَدٌّ بَعْدُ.", - " You Earn today is ": " مَا حَصَلْتَ عَلَيْهِ الْيَوْمَ هُوَ", - " You Have in": "لَدَيْكَ فِي", - "Total points is ": "إِجْمَالِيُّ النِّقَاطِ هُوَ", - "Total Connection Duration:": "إِجْمَالِيُّ مُدَّةِ الاِتِّصَالِ:", - " H and": "سَاعَةٌ وَ", - "Passenger name : ": 'اِسْمُ الرَّاكِبِ', - "Cost Of Trip IS ": 'تَكْلِفَةُ الرِّحْلَةِ', - "Arrival time": 'وَقْتُ الْوُصُولِ ', - "arrival time to reach your point": - 'الْوَقْتُ المُتَوَقَّعُ لِلْوُصُولِ إِلَى وَجْهَتِكَ ', + "عروض وخصومات حصرية دائمًا مع تطبيق سفر", + "Please go to Car Driver": "الرجاء التوجه إلى سائق السيارة", + " wallet due to a previous trip.": "بسبب رحلة سابقة.", + "Submit Question": "اطرح سؤال", + "Please enter your Question.": "الرجاء إدخال سؤالك.", + "Help Details": "تفاصيل المساعدة", + "No trip yet found": "لم يتم حجز أي رحلة بعد", + "No Response yet.": "لا يوجد رد حتى الآن.", + " You Earn today is ": "اللي كسبته النهارده هو", + " You Have in": "عندك في", + "Total points is ": "إجمالي النقاط هو", + "Total Connection Duration:": "إجمالي مدة الاتصال:", + " H and": "ساعة و", + "Passenger name : ": "اسم الراكب", + "Cost Of Trip IS ": "تكلفة الرحلة هي", + "Arrival time": "وقت الوصول", + "arrival time to reach your point": "الوقت المتوقع للوصول إلى وجهتك", "For Speed and scooter trips, the price is calculated dynamically. For Comfort trips, the price is based on time and distance": - 'بِالنِّسْبَةِ لِرِحْلَاتِ السُّرْعَةِ وَالتَّوْصِيلِ، يَتِمُّ حِسَابُ السِّعْرِ بِشَكْلٍ دِينَامِيكِيٍّ. أَمَّا بِالنِّسْبَةِ لِرِحْلَاتِ الرَّاحَةِ، فَيَتِمُّ حِسَابُ السِّعْرِ بِنَاءً عَلَى الْوَقْتِ وَالْمَسَافَةِ.', - "Hello this is Driver": "مَرْحَبًا هَذَا السَّائِقُ", - "Is the Passenger in your Car ?": "هَلِ الرَّاكِبُ فِي سَيَّارَتِكَ؟", + "بالنسبة لمشاوير السرعة والسكوتر، السعر بيتحسب بشكل تلقائي. أما مشاوير الراحة، فالسعر بيكون حسب الوقت والمسافة.", + "Hello this is Driver": "مرحباً، أنا السواق", + "Is the Passenger in your Car ?": "هل الراكب معاك في العربية؟", "Please wait for the passenger to enter the car before starting the trip.": - "لَا تَبْدَأِ الرِّحْلَةَ إِذَا لَمْ يَكُنِ الرَّاكِبُ فِي سَيَّارَتِكَ", - "No ,still Waiting.": "لَا، مَازَالَ فِي الِانْتِظَارِ.", - "I arrive you": "وَصَلْتُ إِلَيْكَ", - "I Arrive your site": "وَصَلْتُ إِلَى مَوْقِعِكَ", + "الرجاء الانتظار لحد ما الراكب يركب العربية قبل ما تبدأ المشوار.", + "No ,still Waiting.": "لأ، لسه منتظر.", + "I arrive you": "أنا وصلت لك", + "I Arrive your site": "أنا وصلت مكانك", "You are not in near to passenger location": - "أَنْتَ غَيْرُ قَرِيبٍ مِنْ مَوْقِعِ الرَّاكِبِ", + "أنت مش قريب من مكان الراكب", "please go to picker location exactly": - "الرَّجَاءُ الذَّهَابُ إِلَى مَوْقِعِ الرَّاكِبِ بِالضَّبْطِ", + "الرجاء الذهاب إلى موقع الراكب بالضبط", "You Can Cancel Trip And get Cost of Trip From": - "يُمْكِنُكَ إِلْغَاءُ الرِّحْلَةِ وَالْحُصُولُ عَلَى تَكْلِفَتِهَا مِنْ", - "Are you sure to cancel?": - "هَلْ أَنْتَ مُتَأَكِّدٌ مِنَ الإِلْغَاءِ؟", - "Yes": 'نَعَمْ', - "Insert Emergincy Number": "أَدْخِلِ رَقْمَ الطَّوَارِئِ", + "ممكن تلغي المشوار وتاخد التكلفة من", + "Are you sure to cancel?": "أنت متأكد إنك عايز تلغي؟", + "Yes": "نعم", + "Insert Emergincy Number": "أدخل رقم الطوارئ", "Best choice for comfort car and flexible route and stops point": - "رحلة مكيفة ومسار متغير لرغبة العميل ونقاط توقف", - "Insert": "إِدْرَاجُ", - "This is for scooter or a motorcycle.": - "هَذَا لِلتَّسْلِيمِ أَوِ الدَّرَّاجَةِ النَّارِيَّةِ", + "أفضل اختيار لعربية مريحة ومسار مرن ونقط وقوف", + "Insert": "إدخال", + "This is for scooter or a motorcycle.": "ده للتوصيل أو للموتوسيكل", "This trip goes directly from your starting point to your destination for a fixed price. The driver must follow the planned route": - '‏رحلة محددة السعر والشريك السائق ملتزم بالمسار المحدد من خلال التطبيق', + "المشوار ده من نقطة البداية لنقطة النهاية بسعر ثابت. والسواق لازم يلتزم بالمسار المحدد.", "You can decline a request without any cost": - "‏يمكنك إلغاء الطلب بدون أي تكلفة", + "تقدر ترفض الطلب من غير أي تكلفة", "Perfect for adventure seekers who want to experience something new and exciting": - "خيار مثالي لللي عايزين يخرجوا من الروتين ويجربوا حاجات جديدة ومثيرة", + "مثالي لمحبي المغامرة اللي عايزين يجربوا حاجات جديدة ومثيرة", "My current location is:": "موقعي الحالي هو:", - "and I have a trip on": "nولدي رحلة على", + "and I have a trip on": "وعندي مشوار على", "App with Passenger": "التطبيق\nمع الراكب", "You will be pay the cost to driver or we will get it from you on next trip": - "ستدفع التكلفة للسائق أو سنحصل عليها منك في الرحلة القادمة", - "Trip has Steps": "الرحلة تتكون من خطوات", + "هتدفع التكلفة للسواق أو هناخدها منك في المشوار اللي جاي", + "Trip has Steps": "الرحلة ليها خطوات", "Distance from Passenger to destination is ": - "المسافة من الراكب إلى الوجهة هي", - "price is": "‏التكلفة", + "المسافة من الراكب للوجهة هي", + "price is": "التكلفة", "This ride type does not allow changes to the destination or additional stops": - "ده نوع الرحلات مش بيسمح بتغيير نقطة الوصول أو الوقوف الإضافي", - "This price may be changed": "خَليْ بالَك السَّعر مُمْكِن يِتغَيَّر", + "نوع المشوار ده ميسمحش بتغيير الوجهة أو إضافة وقفات.", + "This price may be changed": "خلي بالك السعر ممكن يتغير", "No SIM card, no problem! Call your driver directly through our app. We use advanced technology to ensure your privacy.": - "حَتَّى لَو مَفِيش كَارت SIM, مَاتِخَافْش! تُقَدِّر تِكَلِّم سِوَاقَك بِمَنْتَهَى البَسَاطَة عَن طَرِيق التَّطْبِيق بِتَاعِنَا. احنَا بِنَسْتَخْدِم تِكْنُولُوجْيَا حَدِيثَة عَشَان نِحافِظ عَلَى خَصُوصِيَّتَك", + "حتى لو مفيش خط، متقلقش! كلم السواق بتاعك من خلال التطبيق بتاعنا. بنستخدم تكنولوجيا حديثة عشان نحافظ على خصوصيتك.", "This ride type allows changes, but the price may increase": - "ده نوع الرحلات بيسمح بالتغيير بس السعر ممكن يزيد", - - "Select one message": "‏اختر رسالة", + "نوع المشوار ده بيسمح بالتغييرات، بس السعر ممكن يزيد", + "Select one message": "اختار رسالة", "My location is correct. You can search for me using the navigation app": - "المَكَان اللِّي أنا فِيه صَحِيح، مُمْكِن تُدَوِّر عَليَّا مِن خِلَال تَطْبِيق المُلاحَة", - "I'm waiting for you": "مُسْتَنِّيك بِفَارِغ الصَّبْر", + "المكان اللي أنا فيه صح، ممكن تدور عليا من خلال تطبيق الملاحة", + "I'm waiting for you": "أنا في انتظارك", "Hello, I'm at the agreed-upon location": - " أَهْلاً وَسَهْلاً، وَصَلْت لِلْمَكَان اللِّي اِتَّفَقْنَا عَلَيْه", + "أهلاً وسهلاً، وصلت للمكان اللي اتفقنا عليه", "We noticed the speed is exceeding 100 km/h. Please slow down for your safety. If you feel unsafe, you can share your trip details with a contact or call the police using the red SOS button.": - "لَقَد لَاحَظْنَا أَنَّ السُّرْعَة تَتَجَاوَز ١٠٠ كم/سَاعَة. يُرْجَى التَّبَاطُؤ مِن أَجْل سَلَامَتِك. إِذَا كُنْت تَشْعُر بِعَدَم الْأَمَان، يُمْكِنُك مُشَارَكَة تَفَاصِيل رِحْلَتِك مَع جِهَة اِتِّصَال أَو الاِتِّصَال بِالشُّرْطَة بِاسْتِخْدَام زَرّ SOS الْأَحْمَر", - "Warning: Speeding detected!": - "تَحْذِير: تَمَّ رَصْد السُّرْعَة الزَّائِدَة!", + "لاحظنا إن السرعة بتزيد عن 100 كم/ساعة. يرجى التباطؤ حفاظًا على سلامتك. لو حسيت بعدم الأمان، ممكن تشارك تفاصيل رحلتك مع حد تثق فيه أو تتصل بالشرطة عن طريق زر الطوارئ الأحمر.", + "Warning: Speeding detected!": "تحذير: تم رصد السرعة الزائدة!", "Please help! Contact me as soon as possible.": - "الرَّجَاء الْمُسَاعَدَة! اِتَّصِل بِي فِي أَقْرَب وَقْت مُمْكِن", - "Share Trip Details": "مُشَارَكَة تَفَاصِيل الرِّحْلَة", - "Car Plate is ": "‏رَقْم اللَّوْحَة", + "الرجاء المساعدة! اتصل بي في أقرب وقت ممكن", + "Share Trip Details": "مشاركة تفاصيل الرحلة", + "Car Plate is ": "رقم اللوحة", "VIP Order": "طلب VIP", "the 300 points equal 300 L.E for you \nSo go and gain your money": - "اِرْبَح ٣٠٠ جُنَيه! كُلّ ٣٠٠ نُقْطَة تُمْنِحُك ٣٠٠ جُنَيه. اِذْهَب وَاِسْتَفِد مِن نُقَاطِك!", - "the 300 points equal 300 L.E": - 'الـ 300 نقطة تساوي 30 جنيه بالنسبة لك ', + "اكسب 300 جنيه! كل 300 نقطة تساوي 300 جنيه. يلا استغل نقاطك!", + "the 300 points equal 300 L.E": "الـ 300 نقطة تساوي 300 جنيه ليك", "The payment was not approved. Please try again.": - 'لم يتم الموافقة على الدفع. الرجاء المحاولة مرة أخرى.', - "Payment Failed": 'فشل الدفع', - "Error": 'خطأ', - 'This is a scheduled notification.': "هذا إشعار مجدول.", + "لم يتم الموافقة على الدفع. يرجى المحاولة مرة أخرى.", + "Payment Failed": "فشل الدفع", + "Error": "خطأ", + "This is a scheduled notification.": "هذا إشعار مجدول.", "An error occurred during the payment process.": - 'حدث خطأ أثناء عملية الدفع.', - "The payment was approved.": 'تمت الموافقة على الدفع.', - "Payment Successful": 'نجح الدفع', - "No ride found yet": '‏لا يوجد طلبات متوفرة حاليا', - "Accept Order": "‏اقبل الطلب", + "حدث خطأ أثناء عملية الدفع.", + "The payment was approved.": "تمت الموافقة على الدفع.", + "Payment Successful": "نجح الدفع", + "No ride found yet": "مفيش طلبات متاحة حاليًا", + "Accept Order": "اقبل الطلب", "reject your order.": "رفض طلبك.", - "Bottom Bar Example": "مثال لشريط الأسفل", - "Driver phone": '‏رقم السائق', + "Bottom Bar Example": "مثال لشريط التنقل السفلي", + "Driver phone": "رقم السواق", "Statistics": "الإحصائيات", "Origin": "نقطة الانطلاق", - "Destination": 'الوجهة', - "Driver Name": 'اسم السائق', - "Driver Car Plate": 'لوحة السيارة', - "Available for rides": '‏مشاوير متاحة', + "Destination": "الوجهة", + "Driver Name": "اسم السائق", + "Driver Car Plate": "لوحة السيارة", + "Available for rides": "متاح للمشاوير", "Scan Id": "مسح الهوية", - "Camera not initilaized yet": "الكاميرا لم تُثبت بعد", + "Camera not initilaized yet": "الكاميرا لم يتم تشغيلها بعد", "Scan ID MklGoogle": "مسح هوية MklGoogle", "Language": "اللغة", "Jordan": "الأردن", @@ -1079,191 +1083,189 @@ iOS [https://getapp.cc/app/6458734951] "Qatar": "قطر", "Bahrain": "البحرين", "Kuwait": "الكويت", - "But you have a negative salary of": "لكن لديك راتب سلبي بقيمة", + "But you have a negative salary of": "لكن عندك رصيد سالب بقيمة", "Promo Code": "كود ترويجي", "Your trip distance is": "مسافة رحلتك هي", "Enter promo code": "أدخل كود ترويجي", - "You have promo!": "لديك عرض ترويجي!", + "You have promo!": "عندك عرض ترويجي!", "Cost Duration": "تكلفة المدة", "Duration is": "المدة هي", "Leave": "مغادرة", - "Join": "الانضمام", + "Join": "انضمام", "Heading your way now. Please be ready.": - "في طريقي إليك الآن. يرجى الاستعداد.", + "أنا في طريقي إليك الآن. يرجى الاستعداد.", "Approaching your area. Should be there in 3 minutes.": - "اقترب من منطقتك. يجب أن أكون هناك خلال 3 دقائق.", + "أقترب من منطقتك. يفترض أوصل خلال 3 دقايق.", "There's heavy traffic here. Can you suggest an alternate pickup point?": - "هناك حركة مرور كثيفة هنا. هل يمكنك اقتراح نقطة استلام بديلة؟", + "فيه زحمة مرور شديدة هنا. ممكن تقترح مكان تاني للاستلام؟", "This ride is already taken by another driver.": - "تم حجز هذه الرحلة من قبل سائق آخر.", - "You Should be select reason.": "يجب أن تختار السبب.", + "المشوار ده أخده سواق تاني خلاص.", + "You Should be select reason.": "يجب أن تختار سبب.", " \$": " دينار ", - "Waiting for Driver ...": "في انتظار السائق...", - "Latest Recent Trip": "آخر رحلة حديثة", + "Waiting for Driver ...": "في انتظار السواق...", + "Latest Recent Trip": "آخر مشوار عملته", "from your list": "من قائمتك", - "Do you want to change Work location": "هل تريد تغيير موقع العمل؟", - "Do you want to change Home location": "هل تريد تغيير موقع المنزل؟", + "Do you want to change Work location": "عايز تغير مكان شغلك؟", + "Do you want to change Home location": "عايز تغير مكان بيتك؟", "We Are Sorry That we dont have cars in your Location!": "نعتذر لعدم وجود سيارات في موقعك!", "Choose from Map": "اختر من الخريطة", - 'Pick your ride location on the map - Tap to confirm': - 'حدد موقع ‏الالتقاء على الخريطة - اضغط للتأكيد', + "Pick your ride location on the map - Tap to confirm": + "حدد مكان الالتقاء على الخريطة - اضغط للتأكيد", "To Work": "إلى العمل", - 'Are you want to go this site': '‏هل تريد الذهاب إلى هذا المكان', - 'Closest & Cheapest': ' الأقرب ', - "Work Saved": "تم حفظ العمل", - 'Sefer is the ride-hailing app that is safe, reliable, and accessible.': - '"سفر: تطبيق طلب السيارة الآمن والموثوق والمعتمد"', - 'With Sefer, you can get a ride to your destination in minutes.': - 'مع سفر، يمكنك الحصول على رحلة إلى وجهتك في دقائق.', - 'Sefer is committed to safety, and all of our captains are carefully screened and background checked.': - 'تلتزم سفر بالسلامة، ويتم فحص جميع سائقينا وفحص سجلاتهم الشخصية بعناية.', + "Are you want to go this site": "عايز تروح المكان ده؟", + "Closest & Cheapest": "الأقرب والأرخص", + "Work Saved": "تم حفظ مكان العمل", + "Sefer is the ride-hailing app that is safe, reliable, and accessible.": + "سفر هو تطبيق توصيل آمن وموثوق وسهل الاستخدام.", + "With Sefer, you can get a ride to your destination in minutes.": + "مع سفر، تقدر توصل لوجهتك في دقايق.", + "Sefer is committed to safety, and all of our captains are carefully screened and background checked.": + "سفر ملتزمة بالأمان، وكل الكباتن بيتم فحصهم بدقة والتحقق من خلفيتهم.", "To Home": "إلى المنزل", - "Home Saved": "تم حفظ المنزل", - "Destination selected": "تم تحديد الوجهة:", - "Now select start pick": "حدد موقع الانطلاق الآن:", + "Home Saved": "تم حفظ مكان المنزل", + "Destination selected": "تم اختيار الوجهة:", + "Now select start pick": "اختار مكان الانطلاق دلوقتي:", "Pick from map": "اختيار من الخريطة", - "Click here point": "حدد هذا المكان", - "No Car in your site. Sorry!": "لا توجد سيارة في موقعك. آسف!", - "Nearest Car for you about ": "أقرب سيارة لك حوالي ", + "Click here point": "حدد هذه النقطة", + "No Car in your site. Sorry!": "مفيش عربية في موقعك. آسف!", + "Nearest Car for you about ": "أقرب عربية ليك على بعد حوالي ", "N/A": "غير متوفر", "From :": "من:", - "Get Details of Trip": "الحصول على تفاصيل الرحلة", - "If you want add stop click here": "إذا أردت إضافة وقفة انقر هنا", + "Get Details of Trip": "عرض تفاصيل الرحلة", + "If you want add stop click here": "لو عايز تضيف وقفة اضغط هنا", "Driver": "السائق", - "Where you want go ": "إلى أين تريد الذهاب ", + "Where you want go ": "رايح فين؟", "My Card": "بطاقتي", "Start Record": "بدء التسجيل", "Wallet": "المحفظة", - "History of Trip": "ارشيف الرحلات", + "History of Trip": "سجل الرحلات", "Helping Center": "مركز المساعدة", - 'Record saved': '‏تم حفظ التسجيل', - 'Trips recorded': '‏الرحلات المسجلة', - "Select Your Country": 'اختر بلدك', + "Record saved": "تم حفظ التسجيل", + "Trips recorded": "الرحلات المسجلة", + "Select Your Country": "اختر بلدك", "To ensure you receive the most accurate information for your location, please select your country below. This will help tailor the app experience and content to your country.": - "للتأكد من حصولك على أكثر المعلومات دقة لموقعك، يرجى اختيار بلدك أدناه. سيساعد ذلك في تخصيص تجربة التطبيق ومحتواه لبلدك.", - 'Are you sure to delete recorded files': - '‏هل أنت متأكد من حذف الملف الصوتي', - 'Select recorded trip': "‏اختر الملف الصوتي", + "لتلقي أدق المعلومات لموقعك، يرجى اختيار بلدك أدناه. هذا سيساعد على تخصيص تجربة التطبيق والمحتوى لبلدك.", + "Are you sure to delete recorded files": + "أكيد عايز تمسح الملفات الصوتية المسجلة؟", + "Select recorded trip": "اختر الملف الصوتي المسجل", "Card Number": "رقم البطاقة", - "Hi, Where to ": "مرحبا، إلى أين ", - "Pick your destination from Map": "حدد وجهتك من الخريطة", - "Add Stops": "إضافة المحطات", - "Get Direction": "الحصول على الإرشادات", - "Add Location": "إضافة الموقع", + "Hi, Where to ": "مرحباً، رايح فين؟", + "Pick your destination from Map": "اختار وجهتك من الخريطة", + "Add Stops": "إضافة محطات", + "Get Direction": "عرض الاتجاهات", + "Add Location": "إضافة موقع", "Switch Rider": "تبديل الراكب", "You will arrive to your destination after timer end.": - "سوف تصل إلى وجهتك بعد انتهاء العداد.", - "You can cancel trip": "يمكنك إلغاء الرحلة", + "هتوصل وجهتك بعد انتهاء العداد.", + "You can cancel trip": "تقدر تلغي الرحلة", "The driver waitting you in picked location .": - "السائق ينتظرك في الموقع المحدد.", - "10\$ and get 3% discount": "10 دينار والحصول على خصم 3%", - "20\$ and get 4% discount": "20 دينار والحصول على خصم 4%", - "40\$ and get 6% discount": "40 دينار والحصول على خصم 6%", - "100\$ and get 9% discount": "100 دولار والحصول على خصم 9%", - "Pay with Your": "الدفع باستخدام", - "Pay with Credit Card": "الدفع ببطاقة ائتمان", - "Payment History": "تاريخ المدفوعات", - "Show Promos to Charge": "إظهار العروض للشحن", + "السواق منتظرك في المكان اللي اخترته.", + "10\$ and get 3% discount": "10 دينار واحصل على خصم 3%", + "20\$ and get 4% discount": "20 دينار واحصل على خصم 4%", + "40\$ and get 6% discount": "40 دينار واحصل على خصم 6%", + "100\$ and get 9% discount": "100 دولار واحصل على خصم 9%", + "Pay with Your": "ادفع بـ", + "Pay with Credit Card": "ادفع ببطاقة الائتمان", + "Payment History": "سجل المدفوعات", + "Show Promos to Charge": "عرض العروض للشحن", "Point": "نقطة", - 'How many hours would you like to wait?': - "كم عدد الساعات التي تود الانتظار؟", + "How many hours would you like to wait?": "كم ساعة تحب تنتظر؟", "Driver Wallet": "محفظة السائق", - "Choose between those Type Cars": - 'اختر من بين أنواع السيارات التالية', - "hour": ' ساعه', - 'Select Waiting Hours': "• اختر ساعات الانتظار", + "Choose between those Type Cars": "اختار من بين أنواع العربيات دي", + "hour": "ساعة", + "Select Waiting Hours": "اختر ساعات الانتظار", "Total Points is": "إجمالي النقاط هو", "You will receive a code in SMS message": - "سوف تتلقى رمزًا في رسالة SMS", - "Done": 'تم', - "Total Budget from trips is ": "إجمالي الميزانية من الرحلات هو ", + "سوف تتلقى رمزًا في رسالة نصية", + "Done": "تم", + "Total Budget from trips is ": "إجمالي المبلغ المستحق من الرحلات هو", "Total Amount:": "المبلغ الإجمالي:", "Total Budget from trips by\nCredit card is ": - "الميزانية الإجمالية من الرحلات باستخدام\nبطاقة الائتمان هي ", + "إجمالي المبلغ المستحق من الرحلات عن طريق\nبطاقة الائتمان هو", "This amount for all trip I get from Passengers": - "هذا المبلغ الذي حصلت عليه من جميع الرحلات من الركاب", - "Pay from my budget": "الدفع من ميزانيتي", + "ده المبلغ اللي حصلت عليه من كل الرحلات من الركاب", + "Pay from my budget": "ادفع من رصيدي", "This amount for all trip I get from Passengers and Collected For me in": - "هذا المبلغ الذي حصلت عليه من جميع الرحلات من الركاب وتم جمعه لي في", - "You can buy points from your budget": "يمكنك شراء نقاط من ميزانيتك", - "insert amount": "إدراج المبلغ", + "ده المبلغ اللي حصلت عليه من كل الرحلات من الركاب وتم تجميعه لي في", + "You can buy points from your budget": "تقدر تشتري نقاط من رصيدك", + "insert amount": "أدخل المبلغ", "You can buy Points to let you online\nby this list below": - "يمكنك شراء النقاط للبقاء على وضع الاتصال\nمن خلال القائمة أدناه", - "Create Wallet to receive your money": "إنشاء محفظة لاستلام أموالك", - "Enter your feedback here": "أدخل تعليقاتك هنا", - "Please enter your feedback.": "الرجاء إدخال تعليقاتك.", - "Feedback": "تعليق", - "Submit ": "تقديم", - "Click here to Show it in Map": "انقر هنا لعرضه على الخريطة", + "تقدر تشتري نقاط عشان تبقى متصل\nمن القائمة دي تحت", + "Create Wallet to receive your money": "إنشاء محفظة لاستقبال أموالك", + "Enter your feedback here": "اكتب ملاحظاتك هنا", + "Please enter your feedback.": "الرجاء إدخال ملاحظاتك.", + "Feedback": "ملاحظات", + "Submit ": "إرسال", + "Click here to Show it in Map": "اضغط هنا لعرضه على الخريطة", "Canceled": "تم الإلغاء", "Type your Email": "اكتب بريدك الإلكتروني", "No I want": "لا أريد", "Email is": "البريد الإلكتروني هو", "Phone Number is": "رقم الهاتف هو", "Date of Birth is": "تاريخ الميلاد هو", - "Sex is ": "الجنس هو ", + "Sex is ": "النوع هو ", "Car Details": "تفاصيل السيارة", - "VIN is": "رقم الشاصي هو", + "VIN is": "رقم الشاسيه هو", "Color is ": "اللون هو ", - "Make is ": "الشركه الصانعه", - "Model is": "النوع هو", + "Make is ": "الشركة المصنعة", + "Model is": "الموديل هو", "Year is": "السنة هي", "Expiration Date ": "تاريخ الانتهاء ", "Edit Your data": "تعديل بياناتك", - "write vin for your car": "اكتب رقم الشاصي لسيارتك", - "VIN": "رقم الشاصي", - "write Color for your car": "اكتب لون سيارتك", - "write Make for your car": "اكتب صانع سيارتك", - "Make": "الشركه الصانعه", - "write Model for your car": "اكتب نوع سيارتك", - "Model": "النوع", - "write Year for your car": "اكتب سنة الصنع", - "Expiration Date": "تاريخ الانتهاء ", - "write Expiration Date for your car": "اكتب تاريخ انتهاء رخصه سيارتك", - "Tariffs": "التعرفه", + "write vin for your car": "اكتب رقم الشاسيه لعربيتك", + "VIN": "رقم الشاسيه", + "write Color for your car": "اكتب لون عربيتك", + "write Make for your car": "اكتب الشركة المصنعة لعربيتك", + "Make": "الشركة المصنعة", + "write Model for your car": "اكتب موديل عربيتك", + "Model": "الموديل", + "write Year for your car": "اكتب سنة صنع عربيتك", + "Expiration Date": "تاريخ الانتهاء", + "write Expiration Date for your car": "اكتب تاريخ انتهاء رخصة عربيتك", + "Tariffs": "التعريفات", "Minimum fare": "الحد الأدنى للأجرة", "Maximum fare": "الحد الأقصى للأجرة", - "Flag-down fee": "رسوم التشغيل", - "Including Tax": "بما في ذلك الضرائب", - "BookingFee": "رسوم الطلب", + "Flag-down fee": "رسوم فتح العداد", + "Including Tax": "شامل الضريبة", + "BookingFee": "رسوم الحجز", "Morning": "الصباح", "from 07:30 till 10:30 (Thursday, Friday, Saturday, Monday)": - "من 07:30 إلى 10:30 (يوم الخميس، الجمعة، السبت، الإثنين)", + "من 07:30 حتى 10:30 (الخميس، الجمعة، السبت، الاثنين)", "Evening": "المساء", "from 12:00 till 15:00 (Thursday, Friday, Saturday, Monday)": - "من 12:00 إلى 15:00 (يوم الخميس، الجمعة، السبت، الإثنين)", + "من 12:00 حتى 15:00 (الخميس، الجمعة، السبت، الاثنين)", "Night": "الليل", - "You have in account": 'يوجد في حسابك ', - "Select Country": 'اختر الدوله', - "Ride Today : ": 'عدد الرحلات : ', + "You have in account": "عندك في الحساب", + "Select Country": "اختر الدولة", + "Ride Today : ": "عدد رحلات اليوم: ", "After this period\nYou can\'t cancel!": - 'بعد هذه الفتره \nلا تستطيع الغاء الرحله', - "from 23:59 till 05:30": "من 23:59 إلى 05:30", + "بعد الفترة دي\nمش هتقدر تلغي!", + "from 23:59 till 05:30": "من 23:59 حتى 05:30", "Rate Driver": "تقييم السائق", - "Total Cost is ": ' صافي الربح ', - "Write note": 'اكتب ملاحظه', - "Time to arrive": 'وقت الوصول', + "Total Cost is ": "صافي الربح", + "Write note": "اكتب ملاحظة", + "Time to arrive": "وقت الوصول", "Ride Summaries": "ملخصات الرحلات", - "Total Cost": "المبلغ الاجمالي", + "Total Cost": "المبلغ الإجمالي", "Average of Hours of": "متوسط ساعات", " is ON for this month": "في هذا الشهر", "Days": "أيام", "Total Hours on month": "إجمالي الساعات في الشهر", "Counts of Hours on days": "عدد ساعات الأيام", - "OrderId": 'رقم الرحله', - "created time": "وقت الرحله", - "Speed Over": 'سرعة عالية', - "I will slow down": 'حاضر هخفف', - "Map Passenger": 'خارطه الراكب', - "Be Slowly": "خفف شوية من السرعة", + "OrderId": "رقم الرحلة", + "created time": "وقت الرحلة", + "Speed Over": "سرعة عالية", + "I will slow down": "حاضر ههدي السرعة", + "Map Passenger": "خريطة الراكب", + "Be Slowly": "بالراحة شوية في السرعة", "If you want to make Google Map App run directly when you apply order": - "إذا كنت تريد أن تفتح تطبيق خرائط جوجل مباشرة عند طلب الخدمة", - "You can change the language of the app": "يمكنك تغيير لغة التطبيق", - "Your Budget less than needed": 'القيمه المدخله اقل من رصيدك', + "لو عايز تطبيق خرائط جوجل يشتغل تلقائي لما تطلب الخدمة", + "You can change the language of the app": "تقدر تغير لغة التطبيق", + "Your Budget less than needed": "القيمة المدخلة أقل من رصيدك", "You can change the Country to get all features": - 'يمكنك تغيير البلد للحصول على جميع الميزات', - "Change Country": '‏تغيير الدولة', + "تقدر تغير البلد عشان تحصل على كل المميزات", + "Change Country": "تغيير الدولة" }, "tr": { "Sign In by Apple": "Apple'dan Giriş Yapın", diff --git a/lib/views/auth/login_page.dart b/lib/views/auth/login_page.dart index 8cceb25..f9ba352 100644 --- a/lib/views/auth/login_page.dart +++ b/lib/views/auth/login_page.dart @@ -37,461 +37,297 @@ class LoginPage extends StatelessWidget { isleading: false, body: [ if (box.read(BoxName.agreeTerms) != 'agreed') - agreedPage() + _buildAgreementPage(controller) else if (box.read(BoxName.countryCode) == null) - CountryPicker() + _buildCountryPicker() else if (box.read(BoxName.locationPermission) != 'true') - locationPermissionDialog() + _buildLocationPermissionDialog(controller) else - SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - children: [ - Center( - child: Container( - decoration: AppStyle.boxDecoration1, - height: Get.height * .7, - width: Get.width * .9, - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - Image.asset( - 'assets/images/logo.gif', - height: Get.width * .3, - width: Get.width * .3, - fit: BoxFit.fill, - ), - Platform.isIOS && controller.isTest == 0 - ? Container( - decoration: AppStyle.boxDecoration, - child: Column( - children: [ - Form( - key: controller.formKey, - child: Padding( - padding: const EdgeInsets.all(16.0), - child: SingleChildScrollView( - child: Column( - children: [ - TextFormField( - keyboardType: TextInputType - .emailAddress, - controller: controller - .emailController, - decoration: InputDecoration( - focusedBorder: - OutlineInputBorder( - borderSide: - const BorderSide( - color: AppColor - .primaryColor, - width: 2.0, - ), - borderRadius: - BorderRadius.circular( - 10), - ), - fillColor: - AppColor.accentColor, - hoverColor: - AppColor.accentColor, - focusColor: - AppColor.accentColor, - border: const OutlineInputBorder( - borderRadius: - BorderRadius.all( - Radius.circular( - 12))), - labelText: 'Email'.tr, - hintText: - 'Enter your email address' - .tr, - ), - validator: (value) { - if (value!.isEmpty || - (!value.contains('@') || - !value.contains( - '.'))) { - return 'Please enter Your Email.' - .tr; - } - return null; - }, - ), - const SizedBox( - height: 15, - ), - TextFormField( - obscureText: true, - keyboardType: TextInputType - .emailAddress, - controller: controller - .passwordController, - decoration: InputDecoration( - focusedBorder: - OutlineInputBorder( - borderSide: - const BorderSide( - color: AppColor - .primaryColor, - width: 2.0, - ), - borderRadius: - BorderRadius.circular( - 10), - ), - fillColor: - AppColor.accentColor, - hoverColor: - AppColor.accentColor, - focusColor: - AppColor.accentColor, - border: const OutlineInputBorder( - borderRadius: - BorderRadius.all( - Radius.circular( - 12))), - labelText: 'Password'.tr, - hintText: - 'Please enter your phone number.' - .tr, - ), - validator: (value) { - if (value!.isEmpty) { - return 'Please enter Your Password.' - .tr; - } - if (value.length < 6) { - return 'Password must br at least 6 character.' - .tr; - } - return null; - }, - ), - GetBuilder( - builder: (controller) => - controller.isloading - ? const MyCircularProgressIndicator() - : MyElevatedButton( - onPressed: () { - if (controller - .formKey - .currentState! - .validate()) { - controller - .login(); - } - }, - title: - 'Submit'.tr, - ), - ) - ], - ), - ), - ), - ), - const SizedBox( - height: 10, - ), - ], - ), - ) - : Container( - decoration: AppStyle.boxDecoration1, - height: Get.height * .3, - width: Get.width * .8, - child: Center( - child: Text( - 'Sign in with Google for easier email and name entry' - .tr, - textAlign: TextAlign.center, - style: AppStyle.title, - ), - ), - ), - // MyElevatedButton( - // title: 'Sign In by Google'.tr, - // onPressed: () async { - // await GoogleSignInHelper.signInFromLogin(); - // }, - // kolor: AppColor.blueColor, - // ), - InkWell( - onTap: () async { - await GoogleSignInHelper().signInFromLogin(); - }, - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 16, vertical: 10), - decoration: BoxDecoration( - color: AppColor.redColor, - borderRadius: BorderRadius.circular(8), - ), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - const Icon( - FontAwesome.google, - color: AppColor.blueColor, - ), - const SizedBox(width: 8), - Text( - 'Sign In by Google'.tr, - style: const TextStyle( - color: Colors.white, - fontSize: 16, - fontWeight: FontWeight.w500, - ), - ), - ], - ), - ), - ), - - !Platform.isAndroid - ? GestureDetector( - onTap: () async { - User? user = - await authController.signInWithApple(); - if (user != null) { - box.write(BoxName.passengerID, user.uid); - box.write(BoxName.email, user.email); - await controller.loginUsingCredentials( - box - .read(BoxName.passengerID) - .toString(), - box.read(BoxName.email).toString(), - ); - // Navigate to another screen or perform other actions - } else { - Get.snackbar('user not found'.tr, '', - backgroundColor: AppColor.redColor); - } - }, - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 16, vertical: 10), - decoration: BoxDecoration( - color: Colors.black, - borderRadius: BorderRadius.circular(8), - ), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - const Icon( - Icons.apple, - color: Colors.white, - size: 24, - ), - const SizedBox(width: 8), - Text( - 'Sign in with Apple'.tr, - style: const TextStyle( - color: Colors.white, - fontSize: 16, - fontWeight: FontWeight.w500, - ), - ), - ], - ), - ), - ) - : const SizedBox(), - ], - ), - )), - SizedBox( - height: Get.height * .1, - ), - GestureDetector( - onTap: () => Get.to(() => ContactUsPage()), - child: Text( - 'If you need assistance, contact us' - .tr, // Improved wording - style: AppStyle.subtitle, - ), - ), - // Text( - // 'if you dont have account'.tr, - // style: AppStyle.subtitle, - // ), - // AnimatedTextKit( - // onTap: () => Get.to(() => SmsSignupEgypt()), - // animatedTexts: [ - // TypewriterAnimatedText( - // 'Register'.tr, - // textStyle: AppStyle.headTitle2, - // speed: const Duration(milliseconds: 200), - // ), - // ], - // totalRepeatCount: 4, - // pause: const Duration(milliseconds: 200), - // displayFullTextOnTap: true, - // stopPauseOnTap: true, - // ), - // const Spacer(), - const SizedBox( - height: 100, - ), - ], - ), - ), - ) + _buildLoginContent(controller, authController), ], ), ); } - Padding agreedPage() { - return Padding( - padding: const EdgeInsets.all(16), - child: SingleChildScrollView( + Widget _buildLoginContent( + LoginController controller, AuthController authController) { + return SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(16.0), child: Column( + mainAxisAlignment: MainAxisAlignment.center, children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Image.asset( - 'assets/images/notepad.png', - width: Get.width * .2, - ), - SizedBox( - width: Get.width * .7, - child: Text( - 'Accept Ride\'s Terms & Review Privacy Notice'.tr, - style: AppStyle.headTitle2, - ), - ), - ], + Image.asset( + 'assets/images/logo.gif', + height: Get.width * 0.4, + width: Get.width * 0.4, + fit: BoxFit.contain, ), - const SizedBox( - height: 30, - ), - RichText( - text: TextSpan( - text: - 'By selecting "I Agree" below, I have reviewed and agree to the Terms of Use and acknowledge the ' - .tr, - style: AppStyle.title, - children: [ - TextSpan( - text: 'Privacy Notice'.tr, - style: const TextStyle( - decoration: TextDecoration.underline, - color: AppColor.blueColor), - recognizer: TapGestureRecognizer() - ..onTap = () { - Get.defaultDialog( - title: ''.tr, - content: const SizedBox( - height: 400, - width: 400, - child: SingleChildScrollView( - child: - HtmlWidget(AppInformation.privacyPolicy), - ), - )); - }), - TextSpan( - text: '. I am at least 18 years of age.'.tr, - ), - ], + const SizedBox(height: 32), + if (Platform.isIOS && controller.isTest == 0) + _buildEmailPasswordForm(controller) + else + Padding( + padding: const EdgeInsets.only(bottom: 24.0), + child: Text( + 'Sign in for a seamless experience'.tr, + textAlign: TextAlign.center, + style: AppStyle.subtitle, + ), + ), + InkWell( + onTap: () async => await GoogleSignInHelper().signInFromLogin(), + child: _buildSocialButton( + icon: FontAwesome.google, + text: 'Sign In with Google'.tr, + color: AppColor.redColor, ), ), - const SizedBox( - height: 100, - ), - GetBuilder( - builder: (controller) => Column( - children: [ - Row( - children: [ - Checkbox.adaptive( - autofocus: true, - tristate: true, - splashRadius: 25, - activeColor: AppColor.primaryColor, - value: controller.isAgreeTerms, - onChanged: (value) => controller.changeAgreeTerm(), - ), - Text( - 'I Agree'.tr, - style: controller.isAgreeTerms - ? AppStyle.title - : AppStyle.title - .copyWith(color: AppColor.accentColor), - ), - ], - ), - MyElevatedButton( - title: 'Submit'.tr, - onPressed: () => controller.saveAgreementTerms()), - ], + const SizedBox(height: 16), + if (!Platform.isAndroid) + GestureDetector( + onTap: () async { + User? user = await authController.signInWithApple(); + if (user != null) { + box.write(BoxName.passengerID, user.uid); + box.write(BoxName.email, user.email); + await controller.loginUsingCredentials( + box.read(BoxName.passengerID).toString(), + box.read(BoxName.email).toString(), + ); + } else { + Get.snackbar('User not found'.tr, '', + backgroundColor: AppColor.redColor); + } + }, + child: _buildSocialButton( + icon: Icons.apple, + text: 'Sign in with Apple'.tr, + color: Colors.black, + ), ), - ) + const SizedBox(height: 40), + GestureDetector( + onTap: () => Get.to(() => ContactUsPage()), + child: Text( + 'Need assistance? Contact us'.tr, + style: AppStyle.subtitle.copyWith(color: Colors.grey), + ), + ), ], ), ), ); } - locationPermissionDialog() { - return GetBuilder(builder: (controller) { - return Padding( - padding: const EdgeInsets.all(16), - child: Container( - height: Get.height * .4, - decoration: AppStyle.boxDecoration1, - child: Padding( - padding: const EdgeInsets.all(20.0), - child: Center( - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - Text( - 'We use your precise location to find the nearest available driver and provide accurate pickup and dropoff information. You can manage this in Settings.' - .tr, - textAlign: TextAlign.center, - style: AppStyle.title, - ), - TextButton( - onPressed: () { - // Optionally, navigate to app settings for manual permission control - openAppSettings(); - }, - child: Text( - "Open Settings".tr, - style: const TextStyle(color: AppColor.blueColor), + Widget _buildSocialButton({ + required IconData icon, + required String text, + required Color color, + }) { + return Container( + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: color, + borderRadius: BorderRadius.circular(8), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(icon, color: Colors.white), + const SizedBox(width: 12), + Text( + text, + style: const TextStyle( + color: Colors.white, fontSize: 16, fontWeight: FontWeight.w500), + ), + ], + ), + ); + } + + Widget _buildEmailPasswordForm(LoginController controller) { + return Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(12), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.2), + spreadRadius: 2, + blurRadius: 5, + offset: const Offset(0, 3), + ), + ], + ), + child: Form( + key: controller.formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + TextFormField( + keyboardType: TextInputType.emailAddress, + controller: controller.emailController, + decoration: InputDecoration( + labelText: 'Email'.tr, + hintText: 'Your email address'.tr, + border: const OutlineInputBorder(), + ), + validator: (value) => value == null || + value.isEmpty || + !value.contains('@') || + !value.contains('.') + ? 'Enter a valid email'.tr + : null, + ), + const SizedBox(height: 16), + TextFormField( + obscureText: true, + controller: controller.passwordController, + decoration: InputDecoration( + labelText: 'Password'.tr, + hintText: 'Your password'.tr, + border: const OutlineInputBorder(), + ), + validator: (value) => value == null || value.isEmpty + ? 'Enter your password'.tr + : null, + ), + const SizedBox(height: 24), + GetBuilder( + builder: (controller) => controller.isloading + ? const Center(child: CircularProgressIndicator()) + : ElevatedButton( + onPressed: () { + if (controller.formKey.currentState!.validate()) { + controller.login(); + } + }, + child: Text('Submit'.tr), ), - ), - MyElevatedButton( - title: 'Next'.tr, - onPressed: () async { - // if (box.read(BoxName.locationPermission) != 'true') { - // Get.put(MyDialog()).getDialog( - // 'Location Permission is requiered for find drivers' - // .tr, - // 'You can just manage your account!'.tr, () { - // Get.back(); - // Get.to(() { - // PassengerProfilePage(); - // }); - // }); - // } else { - await controller.getLocationPermission(); - // } + ), + ], + ), + ), + ); + } + + Widget _buildAgreementPage(LoginController controller) { + return Padding( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ListTile( + leading: Image.asset('assets/images/notepad.png', width: 40), + title: Text('Terms of Use & Privacy Notice'.tr, + style: AppStyle.headTitle2), + ), + const SizedBox(height: 20), + RichText( + textAlign: TextAlign.left, + text: TextSpan( + style: AppStyle.title, + children: [ + TextSpan( + text: + 'By selecting "I Agree" below, I confirm that I have read and agree to the ' + .tr), + TextSpan( + text: 'Terms of Use'.tr, + style: const TextStyle( + decoration: TextDecoration.underline, + color: AppColor.blueColor), + ), + const TextSpan(text: ' and acknowledge the '), + TextSpan( + text: 'Privacy Notice'.tr, + style: const TextStyle( + decoration: TextDecoration.underline, + color: AppColor.blueColor), + recognizer: TapGestureRecognizer() + ..onTap = () { + Get.defaultDialog( + title: 'Privacy Notice'.tr, + content: const SizedBox( + height: 400, + width: 400, + child: SingleChildScrollView( + child: HtmlWidget(AppInformation.privacyPolicy), + ), + ), + ); }, - kolor: AppColor.greenColor, - ) - ], + ), + TextSpan(text: '. I am at least 18 years old.'.tr), + ], + ), + ), + const SizedBox(height: 40), + Row( + children: [ + Checkbox( + value: controller.isAgreeTerms, + onChanged: (newValue) => controller.changeAgreeTerm(), + activeColor: AppColor.primaryColor, + ), + Text('I Agree'.tr, style: AppStyle.title), + ], + ), + const Spacer(), + Align( + alignment: Alignment.bottomCenter, + child: SizedBox( + width: double.infinity, + child: ElevatedButton( + onPressed: controller.isAgreeTerms + ? () => controller.saveAgreementTerms() + : null, + child: Text('Continue'.tr), ), ), ), - ), - ); - }); + ], + ), + ); + } + + Widget _buildLocationPermissionDialog(LoginController controller) { + return Padding( + padding: const EdgeInsets.all(32), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Icon(Icons.location_on, size: 60, color: AppColor.primaryColor), + const SizedBox(height: 20), + Text( + 'Enable Location Access'.tr, + style: AppStyle.headTitle2, + textAlign: TextAlign.center, + ), + const SizedBox(height: 10), + Text( + 'We need your location to find nearby drivers for pickups and drop-offs.' + .tr, + textAlign: TextAlign.center, + style: AppStyle.title, + ), + const SizedBox(height: 20), + ElevatedButton( + onPressed: () async => await controller.getLocationPermission(), + child: Text('Allow Location Access'.tr), + ), + TextButton( + onPressed: () => openAppSettings(), + child: Text('Open Settings'.tr), + ), + ], + ), + ); + } + + Widget _buildCountryPicker() { + return CountryPicker(); } } diff --git a/lib/views/home/map_page_passenger.dart b/lib/views/home/map_page_passenger.dart index d3e2b92..7c7de00 100644 --- a/lib/views/home/map_page_passenger.dart +++ b/lib/views/home/map_page_passenger.dart @@ -33,7 +33,7 @@ class MapPagePassenger extends StatelessWidget { Get.put(MapPassengerController()); Get.put(MyMenuController()); WidgetsBinding.instance.addPostFrameCallback((_) { - checkForUpdate(context); + // checkForUpdate(context); }); return Scaffold( @@ -53,7 +53,8 @@ class MapPagePassenger extends StatelessWidget { // const HeaderDestination(), const BurcMoney(), const PromoCode(), - const ApplyOrderWidget(), const MapMenuWidget(), + const ApplyOrderWidget(), + const MapMenuWidget(), // hexagonClipper(), const CancelRidePageShow(), CashConfirmPageShown(), diff --git a/lib/views/home/map_widget.dart/apply_order_widget.dart b/lib/views/home/map_widget.dart/apply_order_widget.dart index 2a974d8..37d23de 100644 --- a/lib/views/home/map_widget.dart/apply_order_widget.dart +++ b/lib/views/home/map_widget.dart/apply_order_widget.dart @@ -18,472 +18,34 @@ class ApplyOrderWidget extends StatelessWidget { @override Widget build(BuildContext context) { Color _parseColor(String colorHex) { - if (colorHex.isEmpty) { - return Colors.grey; // Fallback for empty color - } - - // Ensure the string starts with '0xff' for ARGB format + if (colorHex.isEmpty) return Colors.grey; String processedHex = colorHex.replaceFirst('#', '0xff').trim(); - - if (!processedHex.startsWith('0xff')) { - processedHex = '0xff$processedHex'; // Add '0xff' if missing - } - - return Color(int.parse(processedHex)); + return Color(int.parse(processedHex.startsWith('0xff') + ? processedHex + : '0xff$processedHex')); } return GetBuilder(builder: (controller) { - if (controller.statusRide == 'Apply' && - controller.isSearchingWindow == false) { - // double _height = Get.height * .2; + if (controller.statusRide == 'Apply' && !controller.isSearchingWindow) { return Positioned( bottom: 0, left: 0, right: 0, child: Container( - decoration: AppStyle.boxDecoration, - height: Get.height * .36, - child: ListView( + decoration: BoxDecoration( + // More modern BoxDecoration + color: Theme.of(context).cardColor, + borderRadius: + const BorderRadius.vertical(top: Radius.circular(20)), + boxShadow: [BoxShadow(blurRadius: 10, color: Colors.black12)], + ), + padding: const EdgeInsets.all(16), + child: Column( + mainAxisSize: MainAxisSize.min, children: [ - InkWell( - onTap: () { - if (box.read(BoxName.carType) == 'Speed' || - box.read(BoxName.carType) == 'Awfar Car' || - box.read(BoxName.carType) == 'Delivery') { - Get.snackbar( - 'This price is'.tr + - ' ${controller.totalPassenger.toStringAsFixed(2)}' - .tr, - 'This ride type does not allow changes to the destination or additional stops' - .tr, - snackPosition: SnackPosition.BOTTOM, - duration: const Duration(seconds: 2), - backgroundColor: AppColor.yellowColor, - ); - } else { - Get.snackbar( - 'This price may be changed'.tr, - 'This ride type allows changes, but the price may increase' - .tr, - snackPosition: SnackPosition.BOTTOM, - duration: const Duration(seconds: 2), - backgroundColor: AppColor.yellowColor, - ); - } - }, - child: Text.rich( - TextSpan( - children: [ - TextSpan( - text: '${'The driver accept your order for'.tr} ', - style: AppStyle.title, - ), - TextSpan( - text: controller.totalPassenger.toStringAsFixed(2), - style: AppStyle.title.copyWith( - fontWeight: FontWeight.bold, - // fontSize: 22, - color: AppColor.redColor, - ), - ), - TextSpan( - text: ' ${'LE'.tr}', - style: AppStyle.title, - ), - ], - ), - textAlign: TextAlign.center, - ), - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const SizedBox( - width: 10, - ), - Container( - height: Get.height * .31, - width: Get.width * .9, - decoration: AppStyle.boxDecoration, - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Text( - // 'Comfort', - box.read(BoxName.carType - .toString()), //car type fro box after selected - style: AppStyle.title, - ), - const SizedBox( - width: 10, - ), - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - // ColorFiltered( - // colorFilter: ColorFilter.mode( - // _parseColor(controller.colorHex), - // BlendMode.srcIn, - // ), - // child: Image.asset( - // box.read(BoxName.carType) == 'Comfort' - // ? 'assets/images/blob.png' - // : box.read(BoxName.carType) == 'Lady' - // ? 'assets/images/lady.png' // Assuming there's an image for Lady - // : box.read(BoxName.carType) == 'Speed' - // ? 'assets/images/carspeed.png' - // : box.read(BoxName.carType) == - // 'Scooter' - // ? 'assets/images/moto.png' - // : box.read(BoxName.carType) == - // 'Mishwar Vip' - // ? 'assets/images/freeRide.png' - // : box.read(BoxName - // .carType) == - // 'Awfar Car' - // ? 'assets/images/balash.png' - // : box.read(BoxName - // .carType) == - // 'Pink Bike' - // ? 'assets/images/pinkBike.png' - // : box.read(BoxName - // .carType) == - // 'Rayeh Gai' - // ? 'assets/images/roundtrip.png' - // : 'assets/images/carspeed.png', // Default image if none of the above - // width: 80, - // ), - // ), - - Column( - children: [ - Text( - // 'Toyota Camry', - controller.model.toString(), - style: AppStyle.title, - ), - Text( - // 'ر ل 2323', - controller.licensePlate.toString(), - style: AppStyle.title, - ), - ], - ), - const SizedBox( - width: 10, - ), - Text( - // 'Black', - controller.carColor.toString(), - style: AppStyle.title, - ), - const SizedBox( - width: 10, - ), - ColorFiltered( - colorFilter: ColorFilter.mode( - _parseColor(controller.colorHex), - BlendMode.srcIn, - ), - child: Image.asset( - box.read(BoxName.carType) == 'Scooter' || - box.read(BoxName.carType) == - 'Pink Bike' - ? 'assets/images/moto.png' - : 'assets/images/car3.png', - width: 80, - ), - ), - ], - ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 10), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - CircleAvatar( - radius: 25, - backgroundImage: NetworkImage( - '${AppLink.server}/portrate_captain_image/${controller.driverId}.jpg', - ), - child: Builder( - builder: (context) { - return Image.network( - '${AppLink.server}/portrate_captain_image/${controller.driverId}.jpg', - fit: BoxFit.cover, - loadingBuilder: (BuildContext context, - Widget child, - ImageChunkEvent? loadingProgress) { - if (loadingProgress == null) { - return child; // Image is loaded - } else { - return Center( - child: CircularProgressIndicator( - value: loadingProgress - .expectedTotalBytes != - null - ? loadingProgress - .cumulativeBytesLoaded / - (loadingProgress - .expectedTotalBytes ?? - 1) - : null, - ), - ); - } - }, - errorBuilder: (BuildContext context, - Object error, - StackTrace? stackTrace) { - return const Icon( - Icons - .person, // Icon to show when image fails to load - size: - 25, // Adjust the size as needed - color: AppColor - .blueColor, // Color for the error icon - ); - }, - ); - }, - ), - ), - Column( - children: [ - Text( - // 'fadi ahmad', - controller.driverName, - style: AppStyle.title, - ), - Text( - // '⭐ 4.8', - '⭐ ${controller.driverRate}', - style: AppStyle.title, - ), - ], - ), - IconButton( - onPressed: () async { - Get.defaultDialog( - title: 'Select one message', - titleStyle: AppStyle.title, - content: SizedBox( - width: 300, - height: Get.height * .5, - child: ListView( - children: [ - InkWell( - onTap: () { - FirebaseMessagesController() - .sendNotificationToDriverMAP( - 'message From passenger', - 'Hello, I\'m at the agreed-upon location' - .tr, - controller.driverToken - .toString(), - [], - 'ding.wav', - ); - Get.back(); - }, - child: Container( - decoration: - AppStyle.boxDecoration, - child: Padding( - padding: - const EdgeInsets.all( - 10), - child: Text( - 'Hello, I\'m at the agreed-upon location' - .tr, - style: AppStyle.title, - ), - ), - ), - ), - const SizedBox( - height: 5, - ), - InkWell( - onTap: () { - FirebaseMessagesController() - .sendNotificationToDriverMAP( - 'message From passenger', - 'My location is correct. You can search for me using the navigation app' - .tr, - controller.driverToken, - [], - 'ding.wav', - ); - Get.back(); - }, - child: Container( - decoration: - AppStyle.boxDecoration, - child: Padding( - padding: - const EdgeInsets.all( - 10), - child: Text( - 'My location is correct. You can search for me using the navigation app' - .tr, - style: AppStyle.title, - ), - ), - ), - ), - const SizedBox( - height: 5, - ), - InkWell( - onTap: () { - FirebaseMessagesController() - .sendNotificationToDriverMAP( - 'message From passenger', - 'My location is correct. You can search for me using the navigation app' - .tr, - controller.driverToken, - [], - 'ding.wav', - ); - Get.back(); - }, - child: Container( - decoration: - AppStyle.boxDecoration, - child: Padding( - padding: - const EdgeInsets.all( - 10), - child: Text( - 'I\'m waiting for you'.tr, - style: AppStyle.title, - ), - ), - ), - ), - const SizedBox( - height: 5, - ), - InkWell( - onTap: () { - FirebaseMessagesController() - .sendNotificationToDriverMAP( - 'message From passenger', - "How much longer will you be?" - .tr, - controller.driverToken, - [], - 'ding.wav', - ); - Get.back(); - }, - child: Container( - decoration: - AppStyle.boxDecoration, - child: Padding( - padding: - const EdgeInsets.all( - 10), - child: Text( - "How much longer will you be?" - .tr, - style: AppStyle.title, - ), - ), - ), - ), - const SizedBox( - height: 5, - ), - SizedBox( - width: 190, - child: Row( - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Form( - key: controller - .messagesFormKey, - child: SizedBox( - width: 160, - child: MyTextForm( - controller: controller - .messageToDriver, - label: - 'Type Any thing' - .tr, - hint: - 'Type Any thing' - .tr, - type: - TextInputType - .name), - )), - IconButton( - onPressed: () { - FirebaseMessagesController() - .sendNotificationToDriverMAP( - 'message From passenger', - controller - .messageToDriver - .text, - controller - .driverToken, - [], - 'ding.wav'); - controller - .messageToDriver - .clear(); - Get.back(); - }, - icon: const Icon( - Icons.send)) - ], - ), - ) - ], - ), - )); - }, - icon: const Icon( - Icons.message, - color: AppColor.blueColor, - size: 35, - ), - ), - IconButton( - onPressed: () async { - HapticFeedback.heavyImpact(); - // Get.to(() => const CallPage()); - // Get.to(() => PassengerCallPage()); - makePhoneCall(controller.driverPhone); - }, - icon: const Icon( - Icons.call, - color: AppColor.greenColor, - size: 35, - ), - ), - ], - ), - ), - controller.isDriverArrivePassenger - ? const DriverArrivePassengerAndWaitMinute() - : const TimeDriverToPassenger() - ], - ), - ), - const SizedBox( - width: 10, - ), - ], - ) + _buildPriceInfo(context, controller), + const SizedBox(height: 16), + _buildDriverInfoCard(context, controller, _parseColor), ], ), ), @@ -493,45 +55,296 @@ class ApplyOrderWidget extends StatelessWidget { } }); } + + Widget _buildPriceInfo( + BuildContext context, MapPassengerController controller) { + return InkWell( + onTap: () { + String message; + if (box.read(BoxName.carType) == 'Speed' || + box.read(BoxName.carType) == 'Awfar Car' || + box.read(BoxName.carType) == 'Delivery') { + message = + 'This ride type does not allow changes to the destination or additional stops' + .tr; + } else { + message = + 'This ride type allows changes, but the price may increase'.tr; + } + Get.snackbar( + 'This price is'.tr + + ' ${controller.totalPassenger.toStringAsFixed(2)}'.tr, + message, + snackPosition: SnackPosition.BOTTOM, + duration: const Duration(seconds: 2), + backgroundColor: + AppColor.yellowColor.withOpacity(0.8), // More subtle background + ); + }, + child: Center( + child: Text.rich( + TextSpan( + children: [ + TextSpan( + text: '${'The driver accepted your order for'.tr} ', + style: AppStyle.title), + TextSpan( + text: controller.totalPassenger.toStringAsFixed(2), + style: AppStyle.title.copyWith( + fontWeight: FontWeight.bold, color: AppColor.redColor), + ), + TextSpan(text: ' ${'LE'.tr}', style: AppStyle.title), + ], + ), + textAlign: TextAlign.center, + ), + ), + ); + } + + Widget _buildDriverInfoCard(BuildContext context, + MapPassengerController controller, Color Function(String) parseColor) { + return Container( + decoration: BoxDecoration( + color: Theme.of(context).canvasColor, + borderRadius: BorderRadius.circular(10), + border: Border.all(color: Colors.grey.shade200), + ), + child: Column( + children: [ + Padding( + padding: const EdgeInsets.all(12.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(box.read(BoxName.carType.toString()), + style: + AppStyle.title.copyWith(fontWeight: FontWeight.w500)), + Row( + children: [ + _buildCarDetails(context, controller), + const SizedBox(width: 10), + _buildCarImage(controller, parseColor), + ], + ), + ], + ), + ), + const Divider(height: 1, thickness: 1, color: Colors.grey), + Padding( + padding: const EdgeInsets.all(12.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + _buildDriverAvatarAndInfo(controller), + _buildContactButtons(context, controller), + ], + ), + ), + Padding( + padding: + const EdgeInsets.only(left: 12.0, right: 12.0, bottom: 12.0), + child: controller.isDriverArrivePassenger + ? const DriverArrivePassengerAndWaitMinute() + : const TimeDriverToPassenger(), + ), + ], + ), + ); + } + + Widget _buildCarDetails( + BuildContext context, MapPassengerController controller) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(controller.model.toString(), style: AppStyle.title), + Text(controller.licensePlate.toString(), + style: Theme.of(context).textTheme.bodyMedium), + Text(controller.carColor.toString(), + style: Theme.of(context).textTheme.bodyMedium), + ], + ); + } + + Widget _buildCarImage( + MapPassengerController controller, Color Function(String) parseColor) { + return ColorFiltered( + colorFilter: + ColorFilter.mode(parseColor(controller.colorHex), BlendMode.srcIn), + child: Image.asset( + box.read(BoxName.carType) == 'Scooter' || + box.read(BoxName.carType) == 'Pink Bike' + ? 'assets/images/moto.png' + : 'assets/images/car3.png', + height: 60, + ), + ); + } + + Widget _buildDriverAvatarAndInfo(MapPassengerController controller) { + return Row( + children: [ + CircleAvatar( + radius: 30, + backgroundImage: NetworkImage( + '${AppLink.server}/portrate_captain_image/${controller.driverId}.jpg'), + onBackgroundImageError: (exception, stackTrace) => + const Icon(Icons.person, size: 30, color: AppColor.blueColor), + ), + const SizedBox(width: 8), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(controller.driverName, + style: AppStyle.title.copyWith(fontWeight: FontWeight.w500)), + Text('⭐ ${controller.driverRate}', + style: const TextStyle(fontSize: 16, color: Colors.grey)), + ], + ), + ], + ); + } + + Widget _buildContactButtons( + BuildContext context, MapPassengerController controller) { + return Row( + children: [ + IconButton( + onPressed: () => _showContactOptionsDialog(context, controller), + icon: const Icon(Icons.message, color: AppColor.blueColor, size: 28), + ), + IconButton( + onPressed: () { + HapticFeedback.heavyImpact(); + makePhoneCall(controller.driverPhone); + }, + icon: const Icon(Icons.call, color: AppColor.greenColor, size: 28), + ), + ], + ); + } + + void _showContactOptionsDialog( + BuildContext context, MapPassengerController controller) { + Get.defaultDialog( + title: 'Contact Options'.tr, + content: SizedBox( + width: 300, + height: Get.height * .4, + child: ListView( + // shrinkWrap: true, + children: [ + ..._buildPredefinedMessages(controller), + const SizedBox(height: 8), + _buildCustomMessageInput(controller, context), + ], + ), + ), + ); + } + + List _buildPredefinedMessages(MapPassengerController controller) { + const messages = [ + 'Hello, I\'m at the agreed-upon location', + 'My location is correct. You can search for me using the navigation app', + 'I\'m waiting for you', + "How much longer will you be?", + ]; + + return messages + .map((message) => Padding( + padding: const EdgeInsets.only(bottom: 8.0), + child: ElevatedButton( + onPressed: () { + FirebaseMessagesController().sendNotificationToDriverMAP( + 'message From passenger', + message.tr, + controller.driverToken.toString(), + [], + 'ding.wav', + ); + Get.back(); + }, + child: Text(message.tr), + ), + )) + .toList(); + } + + Widget _buildCustomMessageInput( + MapPassengerController controller, BuildContext context) { + return Row( + children: [ + Expanded( + child: Form( + key: controller.messagesFormKey, + child: MyTextForm( + controller: controller.messageToDriver, + label: 'Send a custom message'.tr, + hint: 'Type your message'.tr, + type: TextInputType.text, + ), + ), + ), + IconButton( + onPressed: () { + if (controller.messagesFormKey.currentState!.validate()) { + FirebaseMessagesController().sendNotificationToDriverMAP( + 'message From passenger', + controller.messageToDriver.text, + controller.driverToken, + [], + 'ding.wav', + ); + controller.messageToDriver.clear(); + Get.back(); + } + }, + icon: const Icon(Icons.send), + ), + ], + ); + } } class DriverArrivePassengerAndWaitMinute extends StatelessWidget { - const DriverArrivePassengerAndWaitMinute({ - super.key, - }); + const DriverArrivePassengerAndWaitMinute({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return GetBuilder(builder: (controller) { - return Stack( + return Column( children: [ - LinearProgressIndicator( - backgroundColor: AppColor.accentColor, - color: controller.remainingTimeDriverWaitPassenger5Minute < 60 - ? AppColor.redColor - : AppColor.greenColor, - minHeight: 25, + ClipRRect( borderRadius: BorderRadius.circular(15), - value: - controller.progressTimerDriverWaitPassenger5Minute.toDouble(), + child: LinearProgressIndicator( + backgroundColor: AppColor.accentColor.withOpacity(0.3), + color: controller.remainingTimeDriverWaitPassenger5Minute < 60 + ? AppColor.redColor + : AppColor.greenColor, + minHeight: 20, + value: + controller.progressTimerDriverWaitPassenger5Minute.toDouble(), + ), ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'The driver waiting you in picked location .'.tr, - style: AppStyle.subtitle, - textAlign: TextAlign.center, + const SizedBox(height: 4), + Center( + child: Text.rich( + TextSpan( + children: [ + TextSpan( + text: '${'Driver is waiting at pickup.'.tr} ', + style: AppStyle.subtitle), + TextSpan( + text: controller + .stringRemainingTimeDriverWaitPassenger5Minute, + style: AppStyle.title), + ], ), - const SizedBox( - width: 20, - ), - Text( - controller.stringRemainingTimeDriverWaitPassenger5Minute, - style: AppStyle.title, - ), - ], - ) + textAlign: TextAlign.center, + ), + ), ], ); }); @@ -539,77 +352,50 @@ class DriverArrivePassengerAndWaitMinute extends StatelessWidget { } class TimeDriverToPassenger extends StatelessWidget { - const TimeDriverToPassenger({ - super.key, - }); + const TimeDriverToPassenger({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return GetBuilder(builder: (controller) { return controller.isDriverInPassengerWay == false || controller.timeToPassengerFromDriverAfterApplied > 0 - ? Container( - decoration: AppStyle.boxDecoration, - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 1), - child: Stack( - children: [ - Container( - decoration: AppStyle.boxDecoration, - width: Get.width * .7, - height: 15, - // color: AppColor.yellowColor, - ), - Stack( + ? Column( + children: [ + ClipRRect( + borderRadius: BorderRadius.circular(15), + child: LinearProgressIndicator( + backgroundColor: AppColor.accentColor.withOpacity(0.3), + color: controller + .remainingTimeToPassengerFromDriverAfterApplied < + 60 + ? AppColor.redColor + : AppColor.greenColor, + minHeight: 20, + value: controller + .progressTimerToPassengerFromDriverAfterApplied + .toDouble() + .clamp(0.0, 1.0), + ), + ), + const SizedBox(height: 4), + Center( + child: Text.rich( + TextSpan( children: [ - LinearProgressIndicator( - backgroundColor: AppColor.accentColor, - color: controller - .remainingTimeToPassengerFromDriverAfterApplied < - 60 - ? AppColor.redColor - : AppColor.greenColor, - minHeight: 25, - borderRadius: BorderRadius.circular(15), - value: () { - // Ensure valid value between 0.0 and 1.0 - double progress = controller - .progressTimerToPassengerFromDriverAfterApplied - .toDouble(); - if (progress.isNaN || progress.isInfinite) { - // Handle invalid progress (e.g., set to 0.0) - return 0.0; - } else { - return progress.clamp( - 0.0, 1.0); // Clamp to valid range - } - }(), + TextSpan( + text: '${'Driver is on the way'.tr} ', + style: AppStyle.subtitle, + ), + TextSpan( + text: controller.stringRemainingTimeToPassenger, + style: AppStyle.title, ), - Center( - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'The driver on your way'.tr, - style: AppStyle.title - .copyWith(color: AppColor.yellowColor), - textAlign: TextAlign.center, - ), - const SizedBox( - width: 20, - ), - Text( - controller.stringRemainingTimeToPassenger, - style: AppStyle.title, - ), - ], - ), - ) ], ), - ], + textAlign: TextAlign.center, + ), ), - ), + ], ) : const SizedBox(); }); diff --git a/lib/views/home/map_widget.dart/car_details_widget_to_go.dart b/lib/views/home/map_widget.dart/car_details_widget_to_go.dart index 66d16e9..7f2a3b2 100644 --- a/lib/views/home/map_widget.dart/car_details_widget_to_go.dart +++ b/lib/views/home/map_widget.dart/car_details_widget_to_go.dart @@ -102,20 +102,13 @@ class CarDetailsTypeToChoose extends StatelessWidget { mapPassengerController.isBottomSheetShown && mapPassengerController.rideConfirm == false ? Positioned( - bottom: 0, + bottom: 15, left: 8, right: 8, child: Container( - height: Get.height * .3, + height: Get.height * .32, decoration: BoxDecoration( - gradient: LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [ - AppColor.secondaryColor, - AppColor.secondaryColor, - ], - ), + color: AppColor.secondaryColor, borderRadius: BorderRadius.circular(20), boxShadow: [ BoxShadow( @@ -130,6 +123,7 @@ class CarDetailsTypeToChoose extends StatelessWidget { ), ), child: Column( + mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Padding( padding: const EdgeInsets.all(4), @@ -139,7 +133,7 @@ class CarDetailsTypeToChoose extends StatelessWidget { ), ), Padding( - padding: const EdgeInsets.all(8.0), + padding: const EdgeInsets.all(1.0), child: SizedBox( height: Get.height * .22, // Adjust height as needed child: ListView.separated( @@ -478,73 +472,101 @@ class PromoCode extends StatelessWidget { Get.put(BlinkingController()); return GetBuilder( builder: (mapPassengerController) { - return mapPassengerController.data.isNotEmpty && - mapPassengerController.isBottomSheetShown && - mapPassengerController.rideConfirm == false && - mapPassengerController.promoTaken == false - ? GetBuilder(builder: (blinkingController) { - blinkingController.startBlinking(); - return Positioned( - right: 5, - bottom: Get.height * 0.36, - child: Obx(() { - return AnimatedContainer( - duration: const Duration(milliseconds: 500), - width: 70, // Circle size - height: 70, - decoration: BoxDecoration( - shape: BoxShape.circle, - color: blinkingController.isLightOn.value - ? Colors.yellow - : Colors.grey, // Light on/off effect - border: Border.all( - color: blinkingController - .borderColor.value, // Animated border color - width: 3, - ), - ), - child: IconButton( - onPressed: () { - Get.defaultDialog( - title: 'Insert Your Promo Code'.tr, - content: Form( - key: mapPassengerController.promoFormKey, - child: MyTextForm( - controller: mapPassengerController.promo, - label: 'Insert Your Promo Code'.tr, - hint: 'Enter promo code here'.tr, - type: TextInputType.name, - ), + final showPromoButton = mapPassengerController.data.isNotEmpty && + mapPassengerController.isBottomSheetShown && + !mapPassengerController.rideConfirm && + !mapPassengerController.promoTaken; + + return showPromoButton + ? GetBuilder( + builder: (blinkingController) { + blinkingController.startBlinking(); + return Positioned( + right: 16, // Adjusted from 5 for better spacing + bottom: Get.height * 0.36, + child: InkWell( + onTap: () { + Get.defaultDialog( + title: 'Apply Promo Code'.tr, // More engaging title + content: Padding( + padding: const EdgeInsets.symmetric(vertical: 16), + child: Form( + key: mapPassengerController.promoFormKey, + child: MyTextForm( + controller: mapPassengerController.promo, + label: 'Promo Code'.tr, // Shortened label + hint: 'Enter your promo code' + .tr, // More friendly hint + type: TextInputType.name, + // style: AppStyle.normalTextBlack, // Apply consistent style ), - confirm: MyElevatedButton( - title: 'Ok'.tr, - onPressed: () { - if (mapPassengerController - .promoFormKey.currentState! - .validate()) { - mapPassengerController - .applyPromoCodeToPassenger(context); - Get.back(); - } - })); - }, - icon: const Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon(Icons.local_offer, size: 24), // Promo icon - SizedBox(height: 4), - Text( - "Promo", - style: TextStyle( - fontSize: 12, fontWeight: FontWeight.bold), + ), + ), + confirm: MyElevatedButton( + title: 'Apply'.tr, // Shortened button title + onPressed: () { + if (mapPassengerController + .promoFormKey.currentState! + .validate()) { + mapPassengerController + .applyPromoCodeToPassenger(context); + Get.back(); + } + }, + ), + cancel: OutlinedButton( + onPressed: () => Get.back(), + child: Text('Cancel'.tr), + ), + ); + }, + child: Container( + width: 60, // Slightly smaller for a cleaner look + height: 60, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Colors.white, // Solid white background + border: Border.all( + color: blinkingController.borderColor.value, + width: 2, + ), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.1), + blurRadius: 5, + spreadRadius: 2, ), ], ), + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.local_offer, + size: 24, + color: blinkingController.isLightOn.value + ? Colors.orange + : Colors + .grey.shade600, // Distinct promo color + ), + const SizedBox(height: 2), + Text( + "Promo".tr, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.bold, + color: Colors.black87, + ), + ), + ], + ), + ), ), - ); - }), - ); - }) + ), + ); + }, + ) : const SizedBox(); }, ); @@ -559,51 +581,89 @@ class BurcMoney extends StatelessWidget { return GetBuilder( builder: (mapPassengerController) { final passengerWallet = - double.tryParse(box.read(BoxName.passengerWalletTotal)) ?? - 0.0; // Handle potential parsing errors + double.tryParse(box.read(BoxName.passengerWalletTotal)) ?? 0.0; return mapPassengerController.data.isNotEmpty && mapPassengerController.isBottomSheetShown && - !mapPassengerController.rideConfirm + !mapPassengerController.rideConfirm && + passengerWallet < 0.0 // Simplified condition ? Positioned( bottom: Get.height * .41, - child: Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - if (passengerWallet < 0.0) // Use if statement for clarity - Container( - decoration: AppStyle.boxDecoration.copyWith( - color: AppColor.redColor.withOpacity(.3), - ), - height: 50, - width: Get.width, - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 8), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, + left: 16, // Add left margin for better positioning + right: 16, // Add right margin + child: Container( + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: AppColor.redColor + .withOpacity(0.8), // More prominent color + borderRadius: BorderRadius.circular(8), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.1), + blurRadius: 4, + offset: const Offset(0, 2), + ), + ], + ), + child: Row( + children: [ + const Icon( + Icons.warning_amber_rounded, + color: Colors.white, + size: 24, + ), + const SizedBox(width: 8), + Expanded( + child: Text.rich( + TextSpan( children: [ - IconButton( - onPressed: () async => await Get.find< - TextToSpeechController>() - .speakText('you have a negative balance of' - .tr + - '${passengerWallet.toStringAsFixed(2)}' - ' in your' - .tr + - ' ${AppInformation.appName}' - ' wallet due to a previous trip.' - .tr), - icon: const Icon(Icons.headphones)), - Text( - '${'you have a negative balance of'.tr}${'${passengerWallet.toStringAsFixed(2)}\n${' in your'.tr}'} ${AppInformation.appName}${' wallet due to a previous trip.'.tr}', - textAlign: TextAlign.center, - style: AppStyle.subtitle, + TextSpan( + text: '${'Negative Balance:'.tr} ', + style: AppStyle.subtitle.copyWith( + color: Colors.white, + fontWeight: FontWeight.bold, + ), + ), + TextSpan( + text: + '${'You have a balance of'.tr} ${passengerWallet.toStringAsFixed(2)} ${box.read(BoxName.countryCode) == 'Egypt' ? 'LE'.tr : 'JOD'.tr} ${'due to a previous trip.'.tr}', + style: AppStyle.subtitle.copyWith( + color: Colors.white, + ), ), ], ), + textAlign: TextAlign.start, ), ), - ], + const SizedBox(width: 8), + GestureDetector( + onTap: () async => + await Get.find().speakText( + '${'you have a negative balance of'.tr}${passengerWallet.toStringAsFixed(2)}${' in your'.tr} ${AppInformation.appName}${' wallet due to a previous trip.'.tr}'), + child: const Icon( + Icons.headphones, + color: Colors.white, + ), + ), + const SizedBox(width: 8), + // ElevatedButton( + // onPressed: () { + // Get.to(() => PassengerWallet()); + // }, + // style: ElevatedButton.styleFrom( + // backgroundColor: Colors.white, + // foregroundColor: AppColor.redColor, + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(6), + // ), + // padding: const EdgeInsets.symmetric(horizontal: 12), + // textStyle: const TextStyle(fontWeight: FontWeight.bold), + // ), + // child: Text('Top Up'.tr), + // ), + ], + ), ), ) : const SizedBox(); diff --git a/lib/views/home/map_widget.dart/form_search_places_destenation.dart b/lib/views/home/map_widget.dart/form_search_places_destenation.dart index f4335d2..f7fe836 100644 --- a/lib/views/home/map_widget.dart/form_search_places_destenation.dart +++ b/lib/views/home/map_widget.dart/form_search_places_destenation.dart @@ -12,7 +12,6 @@ import '../../../controller/home/map_passenger_controller.dart'; import '../../../main.dart'; GetBuilder formSearchPlacesDestenation() { - // DbSql sql = DbSql.instance; if (box.read(BoxName.addWork).toString() == '' || box.read(BoxName.addHome).toString() == '') { box.write(BoxName.addWork, 'addWork'); @@ -20,349 +19,271 @@ GetBuilder formSearchPlacesDestenation() { } return GetBuilder( - builder: (controller) => Column( + builder: (controller) => Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), + child: Row( children: [ - Padding( - padding: const EdgeInsets.all(6), - child: Column( - children: [ - Container( - width: Get.width * .9, - height: 40, - decoration: - const BoxDecoration(color: AppColor.secondaryColor), - child: TextField( - decoration: InputDecoration( - border: const OutlineInputBorder( - borderRadius: BorderRadius.only(), - gapPadding: 4, - borderSide: BorderSide( - color: AppColor.redColor, - width: 2, - )), - suffixIcon: const Icon(Icons.search), - hintText: controller.hintTextDestinationPoint, - hintStyle: AppStyle.title, - hintMaxLines: 1, - prefixIcon: IconButton( + Expanded( + child: TextFormField( + controller: controller.placeDestinationController, + onChanged: (value) { + if (controller.placeDestinationController.text.length > 2) { + controller.getPlaces(); + controller.changeHeightPlaces(); + } else if (controller + .placeDestinationController.text.isEmpty) { + controller.clearPlacesDestination(); + controller.changeHeightPlaces(); + } + }, + decoration: InputDecoration( + hintText: controller.hintTextDestinationPoint, + hintStyle: + AppStyle.subtitle.copyWith(color: Colors.grey[600]), + prefixIcon: + const Icon(Icons.search, color: AppColor.primaryColor), + suffixIcon: controller + .placeDestinationController.text.isNotEmpty + ? IconButton( + icon: Icon(Icons.clear, color: Colors.grey[400]), onPressed: () { controller.placeDestinationController.clear(); controller.clearPlacesDestination(); + controller.changeHeightPlaces(); }, - icon: Icon( - Icons.clear, - color: Colors.red[300], - ), - ), - ), - controller: controller.placeDestinationController, - onChanged: (value) { - if (controller - .placeDestinationController.text.length > - 5) { - controller.getPlaces(); - controller.changeHeightPlaces(); - } - }, - // onEditingComplete: () => controller.changeHeight(), - ), + ) + : null, + contentPadding: const EdgeInsets.symmetric( + horizontal: 16.0, vertical: 10.0), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(8.0), + borderSide: BorderSide.none, ), - const SizedBox( - height: 10, + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(8.0), + borderSide: BorderSide(color: AppColor.primaryColor), ), - Container( - decoration: AppStyle.boxDecoration1 - .copyWith(color: AppColor.blueColor), - child: InkWell( - onTap: () { - controller.changeMainBottomMenuMap(); - controller.changePickerShown(); - }, - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 20, vertical: 4), - child: Text( - controller.isAnotherOreder - ? 'Pick from map destination'.tr - : 'Pick from map'.tr, - style: AppStyle.title - .copyWith(color: AppColor.secondaryColor), - ), - ), - )), - const SizedBox( - height: 10, - ), - SizedBox( - height: 50, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - InkWell( - onTap: () async { - if (box.read(BoxName.addWork) == 'addWork') { - controller.workLocationFromMap = true; - controller.changeMainBottomMenuMap(); - controller.changePickerShown(); - } else { - controller.hintTextDestinationPoint = 'To Work'; - final latLng = LatLng( - double.parse( - box.read(BoxName.addWork).split(',')[0]), - double.parse( - box.read(BoxName.addWork).split(',')[1]), - ); - controller.newMyLocation = - controller.newStartPointLocation; - controller.changeMainBottomMenuMap(); - - await controller.getDirectionMap( - '${controller.passengerLocation.latitude},${controller.passengerLocation.longitude}', - '${latLng.latitude},${latLng.longitude}', - ); - controller.currentLocationToFormPlaces = false; - controller.placesDestination = []; - // controller.isCancelRidePageShown = true; - controller.clearPlacesStart(); - controller.clearPlacesDestination(); - controller.passengerStartLocationFromMap = - false; - controller.isPickerShown = false; - controller.bottomSheet(); - controller.showBottomSheet1(); - } - }, - onLongPress: () { - Get.defaultDialog( - title: - 'Do you want to change Work location'.tr, - middleText: '', - confirm: MyElevatedButton( - title: 'Yes'.tr, - onPressed: () { - Get.back(); - controller.workLocationFromMap = true; - controller.changeMainBottomMenuMap(); - controller.changePickerShown(); - })); - }, - child: Container( - width: Get.width * .25, - decoration: BoxDecoration( - color: AppColor.blueColor.withOpacity(.4), - border: Border.all()), - child: Text( - ' ${box.read(BoxName.addWork)}' == 'addWork' - ? 'Add Work'.tr - : 'To Work'.tr, - textAlign: TextAlign.center, - style: AppStyle.title, - ), - ), - ), - InkWell( - onLongPress: () { - Get.defaultDialog( - title: - 'Do you want to change Home location'.tr, - middleText: '', - confirm: MyElevatedButton( - title: 'Yes'.tr, - onPressed: () { - Get.back(); - controller.homeLocationFromMap = true; - controller.changeMainBottomMenuMap(); - controller.changePickerShown(); - })); - }, - onTap: () async { - if (box.read(BoxName.addHome) == 'addHome') { - controller.homeLocationFromMap = true; - controller.changeMainBottomMenuMap(); - controller.changePickerShown(); - } else { - controller.hintTextDestinationPoint = 'To Home'; - final latLng = LatLng( - double.parse( - box.read(BoxName.addHome).split(',')[0]), - double.parse( - box.read(BoxName.addHome).split(',')[1]), - ); - controller.changeMainBottomMenuMap(); - - // controller.newMyLocation = latLng; - await controller.getDirectionMap( - '${controller.passengerLocation.latitude},${controller.passengerLocation.longitude}', - '${latLng.latitude},${latLng.longitude}', - ); - controller.currentLocationToFormPlaces = false; - controller.placesDestination = []; - // controller.isCancelRidePageShown = true; - controller.clearPlacesStart(); - controller.clearPlacesDestination(); - controller.passengerStartLocationFromMap = - false; - controller.isPickerShown = false; - // controller.showBottomSheet1(); - // Get.back(); - controller.showBottomSheet1(); - // controller.newMyLocation = latLng; - controller.update(); - controller.update(); - } - }, - child: Container( - width: Get.width * .25, - decoration: BoxDecoration( - color: AppColor.blueColor.withOpacity(.4), - border: Border.all()), - child: Text( - style: AppStyle.title, - textAlign: TextAlign.center, - '${box.read(BoxName.addHome) == 'addHome' ? 'Add Home'.tr : "To Home".tr} '), - ), - ), - ], - ), - ) - ], - ), // + filled: true, + fillColor: Colors.grey[50], + ), + ), + ), + const SizedBox(width: 8.0), + IconButton( + onPressed: () { + controller.changeMainBottomMenuMap(); + controller.changePickerShown(); + }, + icon: Icon(Icons.location_on_outlined, + color: AppColor.accentColor, size: 30), + tooltip: controller.isAnotherOreder + ? 'Pick destination on map' + : 'Pick on map', ), - // controller.placesDestination.isEmpty - // ? InkWell( - // onTap: () { - // controller.changeMainBottomMenuMap(); - // controller.changePickerShown(); - // }, - // child: Text( - // 'Choose from Map'.tr, - // style: - // AppStyle.title.copyWith(color: AppColor.blueColor), - // ), - // ) - // : const SizedBox(), - Container( - height: controller.placesDestination.isNotEmpty - ? controller.height - : 0, - color: AppColor.secondaryColor, - child: ListView.builder( - itemCount: controller.placesDestination.length, - itemBuilder: (BuildContext context, int index) { - var res = controller.placesDestination[index]; - - // Extract fields with null safety - var title = res['title']?.toString() ?? 'Unknown Place'; - var position = res['position']; - var latitude = position?['lat']; - var longitude = position?['lng']; - var address = - res['address']?['label'] ?? 'Unknown Address'; - var categories = res['categories'] ?? []; - var primaryCategory = categories.isNotEmpty - ? categories[0]['name'] - : 'Unknown Category'; - - return InkWell( - onTap: () async { - if (latitude != null && longitude != null) { - sql.insertMapLocation({ - 'latitude': latitude, - 'longitude': longitude, - 'name': title, - 'rate': 'N/A', - 'createdAt': DateTime.now().toIso8601String(), - // No rating in this structure, adjust as needed - }, TableName.recentLocations); - - controller.passengerLocation = - controller.newMyLocation; - controller.myDestination = - LatLng(latitude, longitude); - controller - .convertHintTextDestinationNewPlaces(index); - - controller.placesDestination = []; - controller.placeDestinationController.clear(); - controller.changeMainBottomMenuMap(); - controller.passengerStartLocationFromMap = true; - controller.isPickerShown = true; - } else { - Toast.show( - context, - 'Invalid location data', - AppColor.redColor, - ); - } - }, - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 10), - child: Column( - children: [ - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Column( - children: [ - const Icon(Icons.place, - size: 20), // Fallback icon for places - IconButton( - onPressed: () async { - if (latitude != null && - longitude != null) { - await sql.insertMapLocation({ - 'latitude': latitude, - 'longitude': longitude, - 'name': title, - 'rate': 'N/A', - }, TableName.placesFavorite); - Toast.show( - context, - '$title ${'Saved Successfully'.tr}', - AppColor.primaryColor, - ); - } else { - Toast.show( - context, - 'Invalid location data', - AppColor.redColor, - ); - } - }, - icon: const Icon(Icons.favorite_border), - ), - ], - ), - Expanded( - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Text( - title, - style: AppStyle.title, - ), - Text( - address, - style: AppStyle.subtitle, - ), - Text( - primaryCategory, - style: AppStyle.subtitle, - ), - ], - ), - ), - ], - ), - const Divider(thickness: 1), - ], - ), - ), - ); - }, - )) ], - )); + ), + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + _buildQuickActionButton( + icon: Icons.work_outline, + text: box.read(BoxName.addWork) == 'addWork' + ? 'Add Work'.tr + : 'To Work'.tr, + onTap: () async { + if (box.read(BoxName.addWork) == 'addWork') { + controller.workLocationFromMap = true; + controller.changeMainBottomMenuMap(); + controller.changePickerShown(); + } else { + _handleQuickAction(controller, BoxName.addWork, 'To Work'); + } + }, + onLongPress: () => + _showChangeLocationDialog(controller, 'Work'), + ), + _buildQuickActionButton( + icon: Icons.home_outlined, + text: box.read(BoxName.addHome) == 'addHome' + ? 'Add Home'.tr + : 'To Home'.tr, + onTap: () async { + if (box.read(BoxName.addHome) == 'addHome') { + controller.homeLocationFromMap = true; + controller.changeMainBottomMenuMap(); + controller.changePickerShown(); + } else { + _handleQuickAction(controller, BoxName.addHome, 'To Home'); + } + }, + onLongPress: () => + _showChangeLocationDialog(controller, 'Home'), + ), + ], + ), + ), + AnimatedContainer( + duration: const Duration(milliseconds: 200), + height: + controller.placesDestination.isNotEmpty ? controller.height : 0, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8.0), + ), + margin: const EdgeInsets.symmetric(horizontal: 16.0), + child: ListView.separated( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemCount: controller.placesDestination.length, + separatorBuilder: (context, index) => + const Divider(height: 1, color: Colors.grey), + itemBuilder: (BuildContext context, int index) { + var res = controller.placesDestination[index]; + var title = res['title']?.toString() ?? 'Unknown Place'; + var position = res['position']; + var latitude = position?['lat']; + var longitude = position?['lng']; + var address = res['address']?['label'] ?? 'Unknown Address'; + var categories = res['categories'] ?? []; + var primaryCategory = categories.isNotEmpty + ? categories[0]['name'] + : 'Unknown Category'; + + return ListTile( + leading: const Icon(Icons.place, size: 30, color: Colors.grey), + title: Text(title, + style: AppStyle.subtitle + .copyWith(fontWeight: FontWeight.w500)), + subtitle: Text(address, + style: TextStyle(color: Colors.grey[600], fontSize: 12)), + trailing: IconButton( + icon: const Icon(Icons.favorite_border, color: Colors.grey), + onPressed: () async { + if (latitude != null && longitude != null) { + await sql.insertMapLocation({ + 'latitude': latitude, + 'longitude': longitude, + 'name': title, + 'rate': 'N/A', + }, TableName.placesFavorite); + Toast.show(context, '$title ${'Saved Successfully'.tr}', + AppColor.primaryColor); + } else { + Toast.show( + context, 'Invalid location data', AppColor.redColor); + } + }, + ), + onTap: () async { + if (latitude != null && longitude != null) { + sql.insertMapLocation({ + 'latitude': latitude, + 'longitude': longitude, + 'name': title, + 'rate': 'N/A', + 'createdAt': DateTime.now().toIso8601String(), + }, TableName.recentLocations); + + controller.passengerLocation = controller.newMyLocation; + controller.myDestination = LatLng(latitude, longitude); + controller.convertHintTextDestinationNewPlaces(index); + + controller.placesDestination = []; + controller.placeDestinationController.clear(); + controller.changeMainBottomMenuMap(); + controller.passengerStartLocationFromMap = true; + controller.isPickerShown = true; + } else { + Toast.show( + context, 'Invalid location data', AppColor.redColor); + } + }, + ); + }, + ), + ), + ], + ), + ); +} + +Widget _buildQuickActionButton({ + required IconData icon, + required String text, + VoidCallback? onTap, + VoidCallback? onLongPress, +}) { + return InkWell( + onTap: onTap, + onLongPress: onLongPress, + child: Container( + padding: const EdgeInsets.all(8.0), + decoration: BoxDecoration( + color: AppColor.blueColor.withOpacity(0.1), + borderRadius: BorderRadius.circular(8.0), + border: Border.all(color: AppColor.blueColor.withOpacity(0.3)), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Icon(icon, color: AppColor.blueColor), + const SizedBox(height: 4.0), + Text( + text, + textAlign: TextAlign.center, + style: AppStyle.title.copyWith( + color: AppColor.blueColor, fontWeight: FontWeight.w500), + ), + ], + ), + ), + ); +} + +void _showChangeLocationDialog( + MapPassengerController controller, String locationType) { + Get.defaultDialog( + title: 'Change $locationType location?'.tr, + middleText: '', + confirm: MyElevatedButton( + title: 'Yes'.tr, + onPressed: () { + Get.back(); + if (locationType == 'Work') { + controller.workLocationFromMap = true; + } else { + controller.homeLocationFromMap = true; + } + controller.changeMainBottomMenuMap(); + controller.changePickerShown(); + }, + ), + ); +} + +void _handleQuickAction( + MapPassengerController controller, String boxName, String hintText) async { + final latLng = LatLng( + double.parse(box.read(boxName).toString().split(',')[0]), + double.parse(box.read(boxName).toString().split(',')[1]), + ); + controller.hintTextDestinationPoint = hintText; + controller.changeMainBottomMenuMap(); + + await controller.getDirectionMap( + '${controller.passengerLocation.latitude},${controller.passengerLocation.longitude}', + '${latLng.latitude},${latLng.longitude}', + ); + controller.currentLocationToFormPlaces = false; + controller.placesDestination = []; + controller.clearPlacesStart(); + controller.clearPlacesDestination(); + controller.passengerStartLocationFromMap = false; + controller.isPickerShown = false; + controller.showBottomSheet1(); } diff --git a/lib/views/home/map_widget.dart/form_search_start.dart b/lib/views/home/map_widget.dart/form_search_start.dart index d16c6b3..ab7afe1 100644 --- a/lib/views/home/map_widget.dart/form_search_start.dart +++ b/lib/views/home/map_widget.dart/form_search_start.dart @@ -9,181 +9,130 @@ import '../../../controller/home/map_passenger_controller.dart'; import '../../../main.dart'; GetBuilder formSearchPlacesStart() { - // DbSql sql = DbSql.instance; return GetBuilder( - builder: (controller) => Column( + builder: (controller) => Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), + child: Row( children: [ - Padding( - padding: const EdgeInsets.all(8), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - width: Get.width * .75, - height: 40, - decoration: - const BoxDecoration(color: AppColor.secondaryColor), - child: TextFormField( - decoration: InputDecoration( - border: const OutlineInputBorder( - borderRadius: BorderRadius.only(), - gapPadding: 4, - borderSide: BorderSide( - color: AppColor.redColor, - width: 2, - )), - suffixIcon: const Icon(Icons.search), - hintText: controller.hintTextStartPoint, - hintStyle: AppStyle.title, - hintMaxLines: 1, - prefixIcon: IconButton( + Expanded( + child: TextFormField( + controller: controller.placeStartController, + onChanged: (value) { + if (controller.placeStartController.text.length > 2) { + // Reduced character limit + controller.getPlacesStart(); + controller.changeHeightStartPlaces(); + } else if (controller.placeStartController.text.isEmpty) { + controller.clearPlacesStart(); + controller.changeHeightPlaces(); // Collapse if empty + } + }, + decoration: InputDecoration( + hintText: controller.hintTextStartPoint, + hintStyle: + AppStyle.subtitle.copyWith(color: Colors.grey[600]), + prefixIcon: + const Icon(Icons.search, color: AppColor.primaryColor), + suffixIcon: controller.placeStartController.text.isNotEmpty + ? IconButton( + icon: Icon(Icons.clear, color: Colors.grey[400]), onPressed: () { controller.placeStartController.clear(); controller.clearPlacesStart(); + controller + .changeHeightPlaces(); // Collapse on clear }, - icon: Icon( - Icons.clear, - color: Colors.red[300], - ), - ), - ), - controller: controller.placeStartController, - onChanged: (value) { - if (controller.placeStartController.text.length > 5) { - controller.getPlacesStart(); - controller.changeHeightStartPlaces(); - } - }, - // onEditingComplete: () => controller.changeHeight(), - ), + ) + : null, + contentPadding: const EdgeInsets.symmetric( + horizontal: 16.0, vertical: 10.0), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(8.0), + borderSide: BorderSide.none, ), - IconButton( - onPressed: () { - controller.startLocationFromMap = true; - controller.changeMainBottomMenuMap(); - controller.changePickerShown(); - }, - icon: const Icon( - Icons.map_outlined, - color: AppColor.yellowColor, - ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(8.0), + borderSide: BorderSide(color: AppColor.primaryColor), ), - ], + filled: true, + fillColor: Colors.grey[50], + ), ), ), - // controller.placesDestination.isEmpty - // ? InkWell( - // onTap: () { - // controller.startLocationFromMap = true; - // controller.changeMainBottomMenuMap(); - // controller.changePickerShown(); - // }, - // child: Text( - // 'Choose from Map Start Point'.tr, - // style: - // AppStyle.title.copyWith(color: AppColor.blueColor), - // ), - // ) - // : const SizedBox(), - Container( - height: - controller.placesStart.isNotEmpty ? controller.height : 0, - color: AppColor.secondaryColor, - child: ListView.builder( - itemCount: controller.placesStart.length, - itemBuilder: (BuildContext context, int index) { - var res = controller.placesStart[index]; - return InkWell( - onTap: () async { - controller.changeHeightPlaces(); - // if (controller.currentLocationToFormPlaces == true) { - // controller.newStartPointLocation = - // controller.myLocation; - // } else { - // controller.myLocation = - // controller.newStartPointLocation; - // } - await sql.insertMapLocation({ - 'latitude': res['geometry']['location']['lat'], - 'longitude': res['geometry']['location']['lng'], - 'name': res['name'].toString(), - 'rate': res['rating'].toString(), - 'createdAt': DateTime.now().toIso8601String(), - }, TableName.recentLocations); - - controller.convertHintTextStartNewPlaces(index); - controller.currentLocationString = res['name']; - controller.placesStart = []; - controller.placeStartController.clear(); - }, - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 10), - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column( - children: [ - Image.network( - res['icon'], - width: 20, - ), - IconButton( - onPressed: () async { - await sql.insertMapLocation({ - 'latitude': res['geometry'] - ['location']['lat'], - 'longitude': res['geometry'] - ['location']['lng'], - 'name': res['name'].toString(), - 'rate': res['rating'].toString(), - }, TableName.placesFavorite); - Toast.show( - context, - '${res['name']} ${'Saved Sucssefully'.tr}', - AppColor.primaryColor); - }, - icon: const Icon(Icons.favorite_border), - ), - ], - ), - Column( - children: [ - Text( - res['name'].toString(), - style: AppStyle.title, - ), - Text( - res['vicinity'].toString(), - style: AppStyle.subtitle, - ), - ], - ), - Column( - children: [ - Text( - 'rate', - style: AppStyle.subtitle, - ), - Text( - res['rating'].toString(), - style: AppStyle.subtitle, - ), - ], - ), - ], - ), - const Divider( - thickness: 1, - ) - ], - ), - ), - ); + const SizedBox(width: 8.0), + IconButton( + onPressed: () { + controller.startLocationFromMap = true; + controller.changeMainBottomMenuMap(); + controller.changePickerShown(); + }, + icon: Icon(Icons.location_on_outlined, + color: AppColor.accentColor, size: 30), + tooltip: 'Choose on Map', + ), + ], + ), + ), + AnimatedContainer( + duration: const Duration(milliseconds: 200), + height: controller.placesStart.isNotEmpty ? controller.height : 0, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8.0), + ), + margin: const EdgeInsets.symmetric(horizontal: 16.0), + child: ListView.separated( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemCount: controller.placesStart.length, + separatorBuilder: (context, index) => + const Divider(height: 1, color: Colors.grey), + itemBuilder: (BuildContext context, int index) { + var res = controller.placesStart[index]; + return ListTile( + leading: Image.network(res['icon'], width: 30, height: 30), + title: Text(res['name'].toString(), + style: AppStyle.subtitle + .copyWith(fontWeight: FontWeight.w500)), + subtitle: Text(res['vicinity'].toString(), + style: TextStyle(color: Colors.grey[600], fontSize: 12)), + trailing: IconButton( + icon: const Icon(Icons.favorite_border, color: Colors.grey), + onPressed: () async { + await sql.insertMapLocation({ + 'latitude': res['geometry']['location']['lat'], + 'longitude': res['geometry']['location']['lng'], + 'name': res['name'].toString(), + 'rate': res['rating'].toString(), + }, TableName.placesFavorite); + Toast.show( + context, + '${res['name']} ${'Saved Successfully'.tr}', + AppColor.primaryColor); }, ), - ) - ], - )); + onTap: () async { + controller.changeHeightPlaces(); + await sql.insertMapLocation({ + 'latitude': res['geometry']['location']['lat'], + 'longitude': res['geometry']['location']['lng'], + 'name': res['name'].toString(), + 'rate': res['rating'].toString(), + 'createdAt': DateTime.now().toIso8601String(), + }, TableName.recentLocations); + + controller.convertHintTextStartNewPlaces(index); + controller.currentLocationString = res['name']; + controller.placesStart = []; + controller.placeStartController.clear(); + }, + ); + }, + ), + ), + ], + ), + ); } diff --git a/lib/views/home/map_widget.dart/main_bottom_Menu_map.dart b/lib/views/home/map_widget.dart/main_bottom_Menu_map.dart index 36e9786..7adce89 100644 --- a/lib/views/home/map_widget.dart/main_bottom_Menu_map.dart +++ b/lib/views/home/map_widget.dart/main_bottom_Menu_map.dart @@ -25,378 +25,316 @@ class MainBottomMenuMap extends StatelessWidget { Widget build(BuildContext context) { Get.put(MapPassengerController()); return GetBuilder( - builder: (controller) => Positioned( - bottom: 3, - left: 5, - right: 5, - child: GestureDetector( - child: AnimatedContainer( - duration: const Duration(milliseconds: 500), - height: controller.mainBottomMenuMapHeight, - decoration: AppStyle.boxDecoration, - child: SingleChildScrollView( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.center, + builder: (controller) => Positioned( + bottom: 16, // Increased bottom padding + left: 16, + right: 16, + child: GestureDetector( + onTap: controller + .changeMainBottomMenuMap, // Make the whole area tappable + child: AnimatedContainer( + duration: const Duration( + milliseconds: 300), // Reduced duration for smoother animation + curve: Curves.easeInOut, // Added animation curve + height: controller.mainBottomMenuMapHeight, + decoration: BoxDecoration( + color: AppColor.secondaryColor, // Use a solid background color + borderRadius: BorderRadius.circular(16), // More rounded corners + boxShadow: [ + BoxShadow( + color: Colors.black12, + blurRadius: 10, + offset: Offset(0, 5), + ), + ], + ), + child: SingleChildScrollView( + physics: const BouncingScrollPhysics(), // Add bouncing effect + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment + .stretch, // Stretch children to full width + children: [ + Padding( + padding: const EdgeInsets.all(16.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - controller.isMainBottomMenuMap - ? Padding( - padding: const EdgeInsets.all(15), - child: InkWell( - onTap: () => - controller.changeMainBottomMenuMap(), - child: Container( - width: Get.width * .8, - height: Get.height * .1, - padding: const EdgeInsets.symmetric( - horizontal: 20, vertical: 10), - decoration: BoxDecoration( - gradient: LinearGradient( - colors: [ - AppColor.blueColor.withOpacity(0.8), - AppColor.blueColor.withOpacity(0.6), - ], - begin: Alignment.topLeft, - end: Alignment.bottomRight, - ), - boxShadow: const [ - BoxShadow( - color: Color.fromARGB( - 255, 237, 230, 230), - blurRadius: 8, - offset: Offset(4, 8), - ), - BoxShadow( - color: Color.fromARGB( - 255, 242, 237, 237), - blurRadius: 8, - offset: Offset(-4, -4), - ), - ], - borderRadius: BorderRadius.circular(30), - ), - - // decoration: AppStyle.boxDecoration1, - child: DefaultTextStyle( - style: AppStyle.title.copyWith( - color: AppColor.secondaryColor), - child: Center( - child: controller.isPickerShown - ? clickPointPosition( - controller, context) - : whereWidgetSmall(controller), - ), - )), - ), - ) - : IconButton( - onPressed: () { - controller.changeMainBottomMenuMap(); - }, - icon: controller.isMainBottomMenuMap - ? const Icon( - Icons.ads_click, - color: AppColor.secondaryColor, - size: 35, - ) - : const Icon( - Icons.arrow_circle_down_rounded, - size: 35, - ), - ), - controller.isMainBottomMenuMap - ? recentPlacesWidget(controller) - : const SizedBox(), - // controller.isMainBottomMenuMap - // ? const SizedBox() - // : InkWell( - // onTap: () async { - // controller.getCurrentLocationFormString(); - // }, - // child: Text( - // 'From :'.tr + - // ' ${controller.currentLocationString}'.tr, - // style: AppStyle.subtitle, - // ), - // ), - controller.isMainBottomMenuMap - ? const SizedBox() - : Column( - children: [ - !controller.isAnotherOreder - ? const SizedBox() - : formSearchPlacesStart(), - formSearchPlacesDestenation(), - const SizedBox( - height: 10, - ), - // MyElevatedButton( - // title: 'Get Details of Trip'.tr, - // onPressed: () async { - // controller.changeMainBottomMenuMap(); - // - // await controller.getMap( - // '${controller.newStartPointLocation.latitude},${controller.newStartPointLocation.longitude}', - // '${controller.newMyLocation.latitude},${controller.newMyLocation.longitude}', - // ); - // controller.currentLocationToFormPlaces = - // false; - // controller.placesDestination = []; - // // controller.isCancelRidePageShown = true; - // controller.clearPlacesStart(); - // controller.clearPlacesDestination(); - // - // controller.showBottomSheet1(); - // Get.back(); - // controller.showBottomSheet1(); - // }), - //todo If you want add stop click here - - InkWell( - onTap: () { - Get.dialog( - Dialog( - shape: RoundedRectangleBorder( - borderRadius: - BorderRadius.circular(16)), - child: Padding( - padding: const EdgeInsets.all(16), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - 'WhatsApp Location Extractor' - .tr, - style: AppStyle.title, - ), - const SizedBox(height: 16), - Form( - key: controller.sosFormKey, - child: Column( - children: [ - MyTextForm( - controller: controller - .whatsAppLocationText, - label: - 'Location Link'.tr, - hint: - 'Paste location link here' - .tr, - type: TextInputType.url, - ), - const SizedBox( - height: 16), - MyElevatedButton( - title: - 'Go to this location' - .tr, - onPressed: () async { - controller - .goToWhatappLocation(); - }, - ) - ], - ), - ), - ], - ), - ), - ), - ); - }, - child: Container( - decoration: BoxDecoration( - gradient: LinearGradient( - colors: [ - Colors.blue[300]!, - Colors.blue[600]! - ], - begin: Alignment.topLeft, - end: Alignment.bottomRight, - ), - borderRadius: BorderRadius.circular(12), - boxShadow: const [ - BoxShadow( - color: Colors.black26, - offset: Offset(0, 4), - blurRadius: 5.0, - ), - ], - ), - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Text( - 'Paste WhatsApp location link here' - .tr, - style: const TextStyle( - color: Colors.white, - fontSize: 16, - fontWeight: FontWeight.bold, - ), - textAlign: TextAlign.center, - ), - ), - ), - ), - CupertinoButton( - child: Text( - !controller.isAnotherOreder - ? 'I want to order for someone else' - .tr - : 'I want to order for myself'.tr, - ), - onPressed: () { - showCupertinoModalPopup( - context: context, - builder: (BuildContext context) => - CupertinoActionSheet( - title: Text('Select Order Type'.tr), - message: Text( - 'Choose who this order is for' - .tr), - actions: [ - CupertinoActionSheetAction( - child: Row( - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - const Icon( - CupertinoIcons.person, - color: CupertinoColors - .activeBlue), - const SizedBox(width: 15), - Text( - 'I want to order for myself' - .tr), - ], - ), - onPressed: () { - controller - .changeisAnotherOreder( - false); - Navigator.pop(context); - }, - ), - CupertinoActionSheetAction( - child: Row( - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - const Icon( - CupertinoIcons.person_2, - color: CupertinoColors - .activeBlue), - const SizedBox(width: 15), - Text( - 'I want to order for someone else' - .tr), - ], - ), - onPressed: () { - controller - .changeisAnotherOreder( - true); - Navigator.pop(context); - }, - ), - ], - cancelButton: - CupertinoActionSheetAction( - isDefaultAction: true, - onPressed: () { - Navigator.pop(context); - }, - child: Text('Cancel'.tr), - ), - ), - ); - }, - ) - ], - ) + Text( + controller.isMainBottomMenuMap + ? 'Where are you going?'.tr + : 'Quick Actions'.tr, + style: AppStyle.title + .copyWith(fontWeight: FontWeight.bold), + ), + IconButton( + onPressed: controller.changeMainBottomMenuMap, + icon: Icon( + controller.isMainBottomMenuMap + ? Icons.keyboard_arrow_down_rounded + : Icons.keyboard_arrow_up_rounded, + size: 28, + color: AppColor.primaryColor, + ), + ), ], ), ), - ), - ), - )); - } - - SizedBox recentPlacesWidget(MapPassengerController controller) { - final textToSpeechController = Get.put(TextToSpeechController()); - return SizedBox( - height: controller.recentPlaces.isEmpty ? 0 : 50, - child: ListView.builder( - itemCount: controller.recentPlaces.length, - scrollDirection: Axis.horizontal, - itemBuilder: (BuildContext context, int index) { - return TextButton( - onPressed: () { - Get.defaultDialog( - title: 'Are you want to go this site'.tr, - titleStyle: AppStyle.title, - middleText: '', - content: IconButton( - onPressed: () { - textToSpeechController - .speakText('Are you want to go this site'.tr); - }, - icon: const Icon( - Icons.headphones, - size: 45, + if (controller.isMainBottomMenuMap) ...[ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: InkWell( + onTap: () => controller.changeMainBottomMenuMap(), + child: Container( + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: AppColor.primaryColor + .withOpacity(0.05), // Subtle background + borderRadius: BorderRadius.circular(12), + ), + child: DefaultTextStyle( + style: AppStyle.subtitle + .copyWith(color: AppColor.writeColor), + child: Center( + child: controller.isPickerShown + ? clickPointPosition(controller, context) + : whereWidgetSmall(controller), + ), + ), + ), + ), ), - ), - confirm: MyElevatedButton( - title: 'Yes'.tr, - onPressed: () async { - Get.back(); - await controller.getLocation(); - await controller.getDirectionMap( - '${controller.passengerLocation.latitude},${controller.passengerLocation.longitude}', - '${controller.recentPlaces[index]['latitude']},${controller.recentPlaces[index]['longitude']}', - ); - // controller.changePickerShown(); - controller.showBottomSheet1(); - - // controller.showBottomSheet1(); - }, - )); - }, - onLongPress: () { - MyDialog().getDialog( - "Are you sure to delete this location?".tr, '', () { - sql.deleteData(TableName.recentLocations, - controller.recentPlaces[index]['id']); - - controller.getFavioratePlaces(); - controller.update(); - Get.back(); - mySnackbarSuccess('deleted'.tr); - }); - }, - child: Container( - decoration: AppStyle.boxDecoration1, - child: Padding( - padding: const EdgeInsets.all(2), - child: Text( - controller.recentPlaces[index]['name'], - style: AppStyle.title, - ), + const SizedBox(height: 12), + if (controller.recentPlaces.isNotEmpty) + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Recent Places'.tr, style: AppStyle.subtitle), + SizedBox( + height: 60, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: controller.recentPlaces.length, + separatorBuilder: (context, index) => + const SizedBox(width: 8), + itemBuilder: (context, index) => + _buildRecentPlaceButton( + controller, context, index), + ), + ), + ], + ), + ), + ] else ...[ + if (!controller.isAnotherOreder) + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: Text( + '${'From:'.tr} ${controller.currentLocationString}' + .tr, + style: AppStyle.subtitle, + ), + ), + const SizedBox(height: 8), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: !controller.isAnotherOreder + ? const SizedBox() + : formSearchPlacesStart(), + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: formSearchPlacesDestenation(), + ), + const SizedBox(height: 16), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: GestureDetector( + onTap: () { + Get.dialog( + AlertDialog( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16)), + title: Text('WhatsApp Location Extractor'.tr), + content: Form( + key: controller.sosFormKey, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + MyTextForm( + controller: + controller.whatsAppLocationText, + label: 'Location Link'.tr, + hint: 'Paste location link here'.tr, + type: TextInputType.url, + ), + const SizedBox(height: 16), + MyElevatedButton( + title: 'Go to this location'.tr, + onPressed: () async { + controller.goToWhatappLocation(); + }, + ), + ], + ), + ), + ), + ); + }, + child: Container( + decoration: BoxDecoration( + color: Colors.blue.shade100, // Lighter background + borderRadius: BorderRadius.circular(12), + border: Border.all( + color: Colors.blue.shade400), // Add a border + ), + padding: const EdgeInsets.all(16), + child: Row( + children: [ + Icon(Icons.link, color: Colors.blue.shade700), + const SizedBox(width: 8), + Expanded( + child: Text( + 'Paste WhatsApp location link'.tr, + style: TextStyle(color: Colors.blue.shade700), + ), + ), + const Icon(Icons.arrow_forward_ios_rounded, + size: 16, color: Colors.blueGrey), + ], + ), + ), + ), + ), + const SizedBox(height: 16), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: OutlinedButton( + onPressed: () { + showCupertinoModalPopup( + context: context, + builder: (BuildContext context) => + CupertinoActionSheet( + title: Text('Select Order Type'.tr), + message: Text('Choose who this order is for'.tr), + actions: [ + CupertinoActionSheetAction( + child: Text('I want to order for myself'.tr), + onPressed: () { + controller.changeisAnotherOreder(false); + Navigator.pop(context); + }, + ), + CupertinoActionSheetAction( + child: Text( + 'I want to order for someone else'.tr), + onPressed: () { + controller.changeisAnotherOreder(true); + Navigator.pop(context); + }, + ), + ], + cancelButton: CupertinoActionSheetAction( + isDefaultAction: true, + onPressed: () { + Navigator.pop(context); + }, + child: Text('Cancel'.tr), + ), + ), + ); + }, + child: Text( + !controller.isAnotherOreder + ? 'Order for someone else'.tr + : 'Order for myself'.tr, + ), + ), + ), + ], + const SizedBox(height: 8), + ], ), ), + ), + ), + ), + ); + } + + Widget _buildRecentPlaceButton( + MapPassengerController controller, BuildContext context, int index) { + final textToSpeechController = Get.find(); + return InkWell( + onTap: () { + Get.defaultDialog( + title: 'Are you want to go this site'.tr, + titleStyle: AppStyle.title, + middleText: '', + content: IconButton( + onPressed: () => textToSpeechController + .speakText('Are you want to go this site'.tr), + icon: const Icon(Icons.headphones, size: 36), + ), + confirm: ElevatedButton( + onPressed: () async { + Get.back(); + await controller.getLocation(); + await controller.getDirectionMap( + '${controller.passengerLocation.latitude},${controller.passengerLocation.longitude}', + '${controller.recentPlaces[index]['latitude']},${controller.recentPlaces[index]['longitude']}', + ); + controller.showBottomSheet1(); + }, + child: Text('Yes'.tr), + ), + cancel: + OutlinedButton(onPressed: () => Get.back(), child: Text('No'.tr)), + ); + }, + onLongPress: () { + MyDialog().getDialog( + "Are you sure to delete this location?".tr, + '', + () { + sql.deleteData(TableName.recentLocations, + controller.recentPlaces[index]['id']); + controller.getFavioratePlaces(); + controller.update(); + Get.back(); + mySnackbarSuccess('deleted'.tr); + }, + ); + }, + child: Chip( + label: Text(controller.recentPlaces[index]['name'], + style: const TextStyle(fontSize: 14)), + onDeleted: () { + MyDialog().getDialog( + "Are you sure to delete this location?".tr, + '', + () { + sql.deleteData(TableName.recentLocations, + controller.recentPlaces[index]['id']); + controller.getFavioratePlaces(); + controller.update(); + Get.back(); + mySnackbarSuccess('deleted'.tr); + }, ); }, ), ); } - TextButton clickPointPosition( + Widget clickPointPosition( MapPassengerController controller, BuildContext context) { return TextButton( onPressed: () async { controller.clearPolyline(); controller.data = []; - //todo add isAnothorOrder if (controller.passengerStartLocationFromMap == true) { controller.newMyLocation = controller.newStartPointLocation; controller.changeMainBottomMenuMap(); @@ -407,16 +345,11 @@ class MainBottomMenuMap extends StatelessWidget { ); controller.currentLocationToFormPlaces = false; controller.placesDestination = []; - // controller.isCancelRidePageShown = true; controller.clearPlacesStart(); controller.clearPlacesDestination(); controller.passengerStartLocationFromMap = false; controller.isPickerShown = false; - // controller.showBottomSheet1(); - // Get.back(); controller.showBottomSheet1(); - // controller.hintTextStartPoint = - // '${controller.newStartPointLocation.latitude.toStringAsFixed(4)} , ${controller.newStartPointLocation.longitude.toStringAsFixed(4)}'; } else if (controller.startLocationFromMap == true) { controller.newMyLocation = controller.newStartPointLocation; controller.hintTextStartPoint = @@ -468,7 +401,7 @@ class MainBottomMenuMap extends StatelessWidget { onPressed: () { Get.back(); })); - } else {} + } if (controller.isWhatsAppOrder == true) { Get.defaultDialog( title: 'Destination selected'.tr, @@ -482,99 +415,64 @@ class MainBottomMenuMap extends StatelessWidget { onPressed: () { Get.back(); })); - } else {} + } } controller.placesDestination = []; controller.placeDestinationController.clear(); controller.showBottomSheet1(); - // Get.back(); - // controller.showBottomSheet1(); - controller.changeMainBottomMenuMap(); }, - child: Row( - children: [ - IconButton( - onPressed: () { - // controller.changeMainBottomMenuMap(); - }, - icon: controller.isMainBottomMenuMap - ? const Icon( - Icons.arrow_circle_up_rounded, - size: 35, - color: AppColor.secondaryColor, - ) - : const Icon( - Icons.arrow_circle_down_rounded, - size: 35, - ), - ), - Text( - controller.passengerStartLocationFromMap - ? 'Pick or Tap to confirm'.tr - // ? 'Pick your ride location on the map - Tap to confirm'.tr - : "Click here point".tr, - style: AppStyle.title.copyWith( - color: AppColor.secondaryColor, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + controller.passengerStartLocationFromMap + ? Icons.location_on + : Icons.location_searching, + size: 20, + color: AppColor.primaryColor, + ), + const SizedBox(width: 8), + Text( + controller.passengerStartLocationFromMap + ? 'Confirm Pick-up Location'.tr + : "Set Location on Map".tr, + style: AppStyle.subtitle.copyWith( fontWeight: FontWeight.bold, - fontSize: 18), - ), - ], + color: AppColor.primaryColor, + ), + ), + ], + ), ), ); } - Row whereWidgetSmall(MapPassengerController controller) { + Widget whereWidgetSmall(MapPassengerController controller) { return Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, + mainAxisAlignment: MainAxisAlignment.center, children: [ - IconButton( - onPressed: () { - controller.changeMainBottomMenuMap(); - }, - icon: controller.isMainBottomMenuMap - ? const Icon( - Icons.ads_click, - color: AppColor.secondaryColor, - size: 35, - ) - : const Icon( - Icons.arrow_circle_down_rounded, - size: 35, - ), - ), + Icon(Icons.location_searching, color: AppColor.primaryColor), + const SizedBox(width: 8), Column( - mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, children: [ - SizedBox( - height: 25, - child: Text('${'Where to'.tr} ${box.read(BoxName.name)}')), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - if (controller.noCarString) - Text('Nearest Car for you about '.tr) - else - Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: AppColor.redColor, - ), - child: null, - ), - if (!controller.noCarString) - Padding( - padding: const EdgeInsets.all(4), - child: Text( - (controller.nearestCar != null - ? controller.nearestDistance.toStringAsFixed(0) - : ''), - ), - ), - ], - ) + Text('${'Where to'.tr} ${box.read(BoxName.name)}', + style: AppStyle.subtitle), + if (controller.noCarString) + Text('Nearest Car: ~'.tr, + style: TextStyle(color: Colors.grey.shade600)) + else + Text( + controller.nearestCar != null + ? 'Nearest Car: ${controller.nearestDistance.toStringAsFixed(0)} m' + : 'No cars nearby'.tr, + style: TextStyle(color: Colors.grey.shade600), + ), ], ), ], @@ -583,100 +481,89 @@ class MainBottomMenuMap extends StatelessWidget { } class FaviouratePlacesDialog extends StatelessWidget { - const FaviouratePlacesDialog({ - super.key, - }); + const FaviouratePlacesDialog({super.key}); @override Widget build(BuildContext context) { Get.put(MapPassengerController()); return GetBuilder( - builder: (controller) => DefaultTextStyle( - style: AppStyle.title, - child: Center( - child: InkWell( - onTap: () async { - List favoritePlaces = - await sql.getAllData(TableName.placesFavorite); - Get.defaultDialog( - title: 'Favorite Places'.tr, - content: SizedBox( - width: Get.width * .8, - height: 300, - child: favoritePlaces.isEmpty - ? Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Icon( - Icons.hourglass_empty_rounded, - size: 99, - color: AppColor.primaryColor, - ), - Text( - 'You Dont Have Any places yet !'.tr, - style: AppStyle.title, - ), - ], - ), - ) - : ListView.builder( - itemCount: favoritePlaces.length, - itemBuilder: (BuildContext context, int index) { - return Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - TextButton( - onPressed: () async { - Get.back(); - await controller.getLocation(); - await controller.getDirectionMap( - '${controller.passengerLocation.latitude},${controller.passengerLocation.longitude}', - '${favoritePlaces[index]['latitude']},${favoritePlaces[index]['longitude']}', - ); - // controller.changePickerShown(); - controller.showBottomSheet1(); - - controller.showBottomSheet1(); - }, - child: Text( - favoritePlaces[index]['name'], - style: AppStyle.title, - ), - ), - IconButton( - onPressed: () async { - await sql.deleteData( - TableName.placesFavorite, - favoritePlaces[index]['id']); - Get.back(); - // ignore: use_build_context_synchronously - Toast.show( - context, - '${'You are Delete'.tr} ${favoritePlaces[index]['name']} from your list', - AppColor.redColor); - // Get.snackbar('Deleted'.tr, - // '${'You are Delete'.tr} ${favoritePlaces[index]['name']} from your list', - // backgroundColor: - // AppColor.accentColor); - }, - icon: const Icon(Icons.favorite_outlined), - ), - ], - ); + builder: (controller) => Center( + child: InkWell( + onTap: () async { + List favoritePlaces = + await sql.getAllData(TableName.placesFavorite); + Get.defaultDialog( + title: 'Favorite Places'.tr, + content: SizedBox( + width: Get.width * .8, + height: 300, + child: favoritePlaces.isEmpty + ? Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Icon( + Icons.star_border_rounded, + size: 99, + color: AppColor.accentColor, + ), + Text( + 'No favorite places yet!'.tr, + style: AppStyle.title, + ), + ], + ), + ) + : ListView.separated( + itemCount: favoritePlaces.length, + separatorBuilder: (context, index) => const Divider(), + itemBuilder: (BuildContext context, int index) { + return ListTile( + leading: + const Icon(Icons.star, color: Colors.amber), + title: Text(favoritePlaces[index]['name'], + style: AppStyle.title), + trailing: IconButton( + icon: const Icon(Icons.delete_outline, + color: Colors.redAccent), + onPressed: () async { + await sql.deleteData(TableName.placesFavorite, + favoritePlaces[index]['id']); + Get.back(); + Toast.show( + context, + '${'Deleted'.tr} ${favoritePlaces[index]['name']} from your favorites', + AppColor.redColor); }, ), - ), - cancel: MyElevatedButton( - title: 'Back'.tr, onPressed: () => Get.back()), - ); - }, - child: Text( - '\u{1F3D8} ' 'Favorite Places'.tr, - style: AppStyle.title, - ), - )), - )); + onTap: () async { + Get.back(); + await controller.getLocation(); + await controller.getDirectionMap( + '${controller.passengerLocation.latitude},${controller.passengerLocation.longitude}', + '${favoritePlaces[index]['latitude']},${favoritePlaces[index]['longitude']}', + ); + controller.showBottomSheet1(); + }, + ); + }, + ), + ), + confirm: MyElevatedButton( + title: 'Back'.tr, onPressed: () => Get.back()), + ); + }, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + const Icon(Icons.star_border_rounded, + color: AppColor.accentColor), + const SizedBox(width: 8), + Text('Favorite Places'.tr, style: AppStyle.title), + ], + ), + ), + ), + ); } } diff --git a/lib/views/home/map_widget.dart/map_menu_widget.dart b/lib/views/home/map_widget.dart/map_menu_widget.dart index efa16dd..7bfa879 100644 --- a/lib/views/home/map_widget.dart/map_menu_widget.dart +++ b/lib/views/home/map_widget.dart/map_menu_widget.dart @@ -15,162 +15,182 @@ import 'package:url_launcher/url_launcher.dart'; import '../../../constant/colors.dart'; import '../../../controller/home/map_passenger_controller.dart'; import '../../notification/notification_page.dart'; -import '../../widgets/icon_widget_menu.dart'; import '../setting_page.dart'; import '../profile/passenger_profile_page.dart'; class MapMenuWidget extends StatelessWidget { - const MapMenuWidget({ - super.key, - }); + const MapMenuWidget({super.key}); @override Widget build(BuildContext context) { return GetBuilder( - builder: (controller) => Stack(children: [ - Positioned( - right: 60, - left: 60, - child: Padding( - padding: const EdgeInsets.only(right: 20), - child: Opacity( - alwaysIncludeSemantics: false, - opacity: 1, // Adjust the opacity value as needed - child: AnimatedContainer( - width: Get.width * .6, - decoration: AppStyle.boxDecoration - .copyWith(color: AppColor.blueColor), - transform: Matrix4.translationValues( - controller.heightMenu * .1, 1, 1), - curve: Curves.easeOutCubic, - clipBehavior: Clip.hardEdge, - duration: const Duration(milliseconds: 300), - height: controller.heightMenu, - child: controller.heightMenuBool - ? Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - IconWidgetMenu( - onpressed: () { + builder: (controller) => Stack( + children: [ + // Top Menu Bar + Positioned( + top: 10, // Adjust as needed + left: 0, + right: 0, + child: SafeArea( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + // GestureDetector( + // onTap: controller.getDrawerMenu, + // child: Container( + // padding: const EdgeInsets.all(10), + // decoration: AppStyle.boxDecoration + // .copyWith(color: AppColor.blueColor), + // child: const Icon(Icons.menu, color: Colors.white), + // ), + // ), + if (controller.heightMenuBool) + Expanded( + child: AnimatedContainer( + duration: const Duration(milliseconds: 300), + height: 50, // Fixed height for the top menu + margin: const EdgeInsets.only(left: 10), + decoration: AppStyle.boxDecoration + .copyWith(color: AppColor.blueColor), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + IconButton( + onPressed: () { Get.to( () => const NotificationPage(), transition: Transition.circularReveal, ); }, - title: 'Notifications'.tr, - icon: Icons.notifications), - IconWidgetMenu( - onpressed: () { - Get.to( - () => PassengerProfilePage(), - transition: Transition.zoom, - ); - }, - icon: Icons.person, - title: 'Profile'.tr, - ), - IconWidgetMenu( - title: 'Home'.tr, - onpressed: () { - Get.to( - () => const SettingPage(), - transition: Transition.downToUp, - curve: Curves.easeInOutExpo, - ); + icon: const Icon(Icons.notifications, + color: Colors.white), + ), + IconButton( + onPressed: () { + Get.to(() => PassengerProfilePage(), + transition: Transition.zoom); }, - icon: Icons.settings), - ], - ) - : const SizedBox(), // Choose the desired overlay color - )), + icon: const Icon(Icons.person, + color: Colors.white), + ), + IconButton( + onPressed: () { + Get.to(() => const SettingPage(), + transition: Transition.downToUp, + curve: Curves.easeInOutExpo); + }, + icon: const Icon(Icons.settings, + color: Colors.white), + ), + ], + ), + ), + ), + ], + ), + ), + ), ), - ), - Positioned( - right: 5, - top: 80, + // Side Drawer (Main Menu) + Positioned( + top: 80, // Adjust as needed + left: 10, child: AnimatedContainer( duration: const Duration(milliseconds: 300), - decoration: AppStyle.boxDecoration1, width: controller.widthMenu, - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - IconMainPageMap( - onTap: () { - Get.to(() => const PassengerWallet()); - }, - title: 'My Wallet'.tr, - icon: Icons.wallet, - ), - IconMainPageMap( - onTap: () async { - Get.to(() => const OrderHistory()); - }, - title: 'Order History'.tr, - icon: Icons.history, - ), - IconMainPageMap( - onTap: () { - Get.to(() => ContactUsPage()); - }, - title: "Contact Us".tr, - icon: Icons.contact_page, - ), - ], - ), - )), - Positioned( - left: 5, - top: 80, - child: AnimatedContainer( - duration: const Duration(milliseconds: 300), - decoration: AppStyle.boxDecoration1, - width: controller.widthMenu, - height: Get.height * .3, - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - IconMainPageMap( - onTap: () async { - final String driverAppUrl; - if (defaultTargetPlatform == TargetPlatform.android) { - driverAppUrl = - 'https://play.google.com/store/apps/details?id=com.sefer_driver&pli=1'; // Replace with your driver app's Play Store URL - } else if (defaultTargetPlatform == TargetPlatform.iOS) { - driverAppUrl = - 'https://apps.apple.com/app/sefer-driver/id6502189302'; // Replace with your driver app's App Store ID - } else { - // Handle other platforms or unknown platform (optional) - return; - } + constraints: const BoxConstraints( + maxWidth: 250), // Add max width constraint - if (await canLaunchUrl(Uri.parse(driverAppUrl))) { - await launchUrl(Uri.parse(driverAppUrl)); - } else { - throw 'Could not launch app store URL'; - } - }, - title: 'Driver'.tr, - icon: WeatherIcons.wi_moon_14, + child: ClipRRect( + borderRadius: BorderRadius.circular(15), + child: Material( + color: Colors.white, // Background color of the drawer + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + IconMainPageMap( + onTap: () { + Get.to(() => const PassengerWallet()); + }, + title: 'My Wallet'.tr, + icon: Icons.wallet, + ), + IconMainPageMap( + onTap: () async { + Get.to(() => const OrderHistory()); + }, + title: 'Order History'.tr, + icon: Icons.history, + ), + IconMainPageMap( + onTap: () { + Get.to(() => ContactUsPage()); + }, + title: "Contact Us".tr, + icon: Icons.contact_page, + ), + IconMainPageMap( + onTap: () async { + final String driverAppUrl; + if (defaultTargetPlatform == TargetPlatform.android) { + driverAppUrl = + 'https://play.google.com/store/apps/details?id=your_android_driver_app_id'; // Replace with your driver app's Play Store URL + } else if (defaultTargetPlatform == + TargetPlatform.iOS) { + driverAppUrl = + 'https://apps.apple.com/app/your_ios_driver_app_id'; // Replace with your driver app's App Store ID + } else { + // Handle other platforms or unknown platform (optional) + return; + } + + try { + final Uri url = Uri.parse(driverAppUrl); + if (await canLaunchUrl(url)) { + await launchUrl(url); + } else { + Get.snackbar( + 'Error', + 'Could not launch driver app store.', + snackPosition: SnackPosition.BOTTOM, + ); + } + } catch (e) { + debugPrint('Error launching URL: $e'); + Get.snackbar( + 'Error', + 'Could not open the link.', + snackPosition: SnackPosition.BOTTOM, + ); + } + }, + title: 'Driver'.tr, + icon: WeatherIcons.wi_moon_14, + ), + IconMainPageMap( + onTap: () { + Get.to(() => ComplaintPage()); + }, + title: 'Complaint'.tr, + icon: Icons.feedback, + ), + IconMainPageMap( + onTap: () { + Get.to(() => const PromosPassengerPage()); + }, + title: 'Promos'.tr, + icon: Icons.monetization_on, + ), + ], ), - IconMainPageMap( - onTap: () { - Get.to(() => ComplaintPage()); - }, - title: 'Complaint'.tr, - icon: Icons.feedback, - ), - IconMainPageMap( - onTap: () { - Get.to(() => const PromosPassengerPage()); - }, - title: 'Promos'.tr, - icon: Icons.monetization_on, - ), - ], + ), ), - )) - ]), + ), + ), + ], + ), ); } } @@ -189,29 +209,21 @@ class IconMainPageMap extends StatelessWidget { @override Widget build(BuildContext context) { - return FutureBuilder( - future: Future.delayed(const Duration(milliseconds: 400)), - builder: (context, snapshot) { - return GestureDetector( - onTap: onTap, - child: SizedBox( - height: Get.height * .1, - width: double.maxFinite, - // decoration: AppStyle.boxDecoration, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - children: [ - Icon(icon), - Text( - title.tr, - style: AppStyle.subtitle, - ), - ], - ), - ), + return InkWell( + onTap: onTap, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 1), + child: Row( + children: [ + Icon(icon, size: 24), + const SizedBox(width: 16), + Text( + title.tr, + style: AppStyle.subtitle, ), - ); - }); + ], + ), + ), + ); } } diff --git a/lib/views/home/map_widget.dart/ride_begin_passenger.dart b/lib/views/home/map_widget.dart/ride_begin_passenger.dart index cf919a1..2e177bc 100644 --- a/lib/views/home/map_widget.dart/ride_begin_passenger.dart +++ b/lib/views/home/map_widget.dart/ride_begin_passenger.dart @@ -15,296 +15,252 @@ import '../../../controller/functions/toast.dart'; import '../../../controller/home/map_passenger_controller.dart'; class RideBeginPassenger extends StatelessWidget { - const RideBeginPassenger({ - super.key, - }); + const RideBeginPassenger({super.key}); @override Widget build(BuildContext context) { ProfileController profileController = Get.put(ProfileController()); AudioRecorderController audioController = Get.put(AudioRecorderController()); - // Get.put(MapPassengerController()); + return GetBuilder(builder: (controller) { - if (controller.statusRide == 'Begin' || !controller.statusRideFromStart) { + if (controller.statusRide == 'Begin') { return Positioned( left: 10, right: 10, bottom: 10, - child: Container( - decoration: AppStyle.boxDecoration, - height: controller.statusRide == 'Begin' ? Get.height * .33 : 0, - // width: 100, + child: Card( + // Wrapped in a Card + elevation: 5, + shape: + RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), child: Padding( - padding: const EdgeInsets.all(8.0), + padding: const EdgeInsets.all(15.0), child: Column( - mainAxisAlignment: MainAxisAlignment.spaceAround, + mainAxisSize: MainAxisSize.min, // Use minimum space children: [ Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ CircleAvatar( radius: 30, backgroundImage: NetworkImage( - '${AppLink.server}/portrate_captain_image/${controller.driverId}.jpg'), + '${AppLink.server}/portrate_captain_image/${controller.driverId}.jpg', + ), ), - Column( - children: [ - Container( - decoration: AppStyle.boxDecoration, - child: Text( - controller.driverName, - style: AppStyle.title, - ), - ), - Container( - decoration: AppStyle.boxDecoration, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, + const SizedBox(width: 10), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(controller.driverName, style: AppStyle.title), + Row( children: [ - Text( - controller.make, - style: AppStyle.title, - ), - Text( - controller.model, - style: AppStyle.title, - ), + Text(controller.make, style: AppStyle.subtitle), + const SizedBox(width: 5), + Text(controller.model, + style: AppStyle.subtitle), ], ), - ), - ], - ), - Column( - children: [ - const Text(''), - Container( - decoration: AppStyle.boxDecoration, - child: Padding( - padding: - const EdgeInsets.symmetric(horizontal: 4), - child: Text( - controller.licensePlate, - style: AppStyle.title, - ), - ), - ), - ], + ], + ), ), Column( + crossAxisAlignment: CrossAxisAlignment.end, children: [ - Container( - decoration: AppStyle.boxDecoration, - child: Padding( - padding: const EdgeInsets.all(3), - child: Text( - '${box.read(BoxName.carType)}', - style: AppStyle.title, - ), - ), + Text( + controller.licensePlate, + style: AppStyle.title.copyWith(fontSize: 16), ), Text( - '${controller.driverRate} 📈', - style: AppStyle.title, + '${box.read(BoxName.carType)}', + style: AppStyle.title.copyWith(fontSize: 16), + ), + Text( + '${controller.driverRate} ⭐️', + style: AppStyle.title + .copyWith(color: AppColor.greenColor), ), ], ), ], ), - // SizedBox( - // height: 5, - // ), + const SizedBox(height: 15), Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ - InkWell( - onTap: () { - controller.getDialog('Arrival time'.tr, - 'arrival time to reach your point'.tr, () {}); - }, - child: Container( - width: Get.width * .15, - decoration: AppStyle.boxDecoration, + SizedBox( + width: Get.width * 0.18, + child: InkWell( + onTap: () => controller.getDialog( + 'Arrival time'.tr, + 'arrival time to reach your point'.tr, + () {}, + ), child: Column( children: [ - Text( - '⏱️', - style: AppStyle.title, - ), - Text( - controller.arrivalTime, - style: AppStyle.title, - ), + const Icon(Icons.timer_outlined, size: 28), + Text(controller.arrivalTime, + style: AppStyle.title), ], ), ), ), - InkWell( - onTap: () { - controller.getDialog( - 'Price of trip'.tr, - 'For Speed and Delivery trips, the price is calculated dynamically. For Comfort trips, the price is based on time and distance' - .tr, () { - Get.back(); - }); - }, - child: Container( - width: Get.width * .15, - decoration: AppStyle.boxDecoration, + SizedBox( + width: Get.width * 0.18, + child: InkWell( + onTap: () => controller.getDialog( + 'Price of trip'.tr, + 'For Speed and Delivery trips, the price is calculated dynamically. For Comfort trips, the price is based on time and distance' + .tr, + () => Get.back(), + ), child: Column( children: [ + const Icon(Icons.monetization_on, size: 28), Text( - '💵 ', - style: AppStyle.title, - ), - Text( - controller.totalPassenger.toStringAsFixed(2), - style: AppStyle.title, - ), + '${controller.totalPassenger.toStringAsFixed(2)}', + style: AppStyle.title), ], ), ), ), - Container( - width: Get.width * .15, - decoration: AppStyle.boxDecoration, + SizedBox( + width: Get.width * 0.18, child: IconButton( - onPressed: () => Get.to( - () => ComplaintPage(), - transition: Transition.downToUp, - ), - icon: const Icon( - Icons.note_add, - color: AppColor.redColor, - ), - tooltip: ' Add Note', // Optional tooltip for clarity + onPressed: () => Get.to(() => ComplaintPage(), + transition: Transition.downToUp), + icon: const Icon(Icons.note_add, + color: AppColor.redColor), + tooltip: 'Add Note', ), ), - Container( - width: Get.width * .15, - decoration: AppStyle.boxDecoration, - child: audioController.isRecording == false - ? IconButton( - onPressed: () async { - await audioController.startRecording(); - Toast.show(context, 'Start Record'.tr, - AppColor.greenColor); - }, - icon: const Icon( - Icons.play_circle_fill_outlined, - color: AppColor.greenColor, - ), - tooltip: - ' Add Note', // Optional tooltip for clarity - ) - : IconButton( - onPressed: () async { - await audioController.stopRecording(); - Toast.show(context, 'Record saved'.tr, - AppColor.greenColor); - }, - icon: const Icon( - Icons.stop_circle, - color: AppColor.greenColor, - ), - tooltip: - ' Add Note', // Optional tooltip for clarity - ), + SizedBox( + width: Get.width * 0.18, + child: IconButton( + onPressed: () async { + if (audioController.isRecording == false) { + await audioController.startRecording(); + Toast.show(context, 'Start Record'.tr, + AppColor.greenColor); + } else { + await audioController.stopRecording(); + Toast.show(context, 'Record saved'.tr, + AppColor.greenColor); + } + }, + icon: Icon( + audioController.isRecording == false + ? Icons.mic_none + : Icons.mic_off, + color: AppColor.greenColor, + ), + tooltip: audioController.isRecording == false + ? 'Start Recording' + : 'Stop Recording', + ), ), ], ), + const SizedBox(height: 15), Stack( + alignment: Alignment.center, children: [ - // StreamCounter(), LinearProgressIndicator( - backgroundColor: AppColor.accentColor, + backgroundColor: AppColor.accentColor + .withOpacity(0.3), // Added background color: controller.remainingTimeTimerRideBegin < 60 ? AppColor.redColor : AppColor.greenColor, - minHeight: 25, - borderRadius: BorderRadius.circular(15), + minHeight: 20, + borderRadius: BorderRadius.circular(10), value: controller.progressTimerRideBegin.toDouble(), ), - Center( - child: Text( - controller.stringRemainingTimeRideBegin, - style: AppStyle.title, - ), - ) + Text( + controller.stringRemainingTimeRideBegin, + style: AppStyle.title.copyWith(fontSize: 14), + ), ], ), + const SizedBox(height: 15), Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ - Container( - decoration: AppStyle.boxDecoration, - width: Get.width * .15, - child: IconButton( - onPressed: () async { - if (box.read(BoxName.sosPhonePassenger) == null) { - { - await profileController.updatField( - 'sosPhone', TextInputType.phone); - box.write(BoxName.sosPhonePassenger, - profileController.prfoileData['sosPhone']); - } - } else { - makePhoneCall('122'); - // box.read(BoxName.sosPhonePassenger)); - } - }, - icon: const Icon( - Icons.sos_rounded, - color: AppColor.redColor, - ), + SizedBox( + width: Get.width * 0.18, + child: Column( + children: [ + IconButton( + onPressed: () async { + if (box.read(BoxName.sosPhonePassenger) == + null) { + await profileController.updatField( + 'sosPhone', TextInputType.phone); + box.write( + BoxName.sosPhonePassenger, + profileController + .prfoileData['sosPhone']); + } else { + makePhoneCall('122'); + } + }, + icon: const Icon(Icons.sos_rounded, + color: AppColor.redColor), + ), + Text('SOS', style: AppStyle.title), + ], ), ), - Container( - decoration: AppStyle.boxDecoration, - width: Get.width * .15, - child: IconButton( - onPressed: () async { - if (box.read(BoxName.sosPhonePassenger) == null || - box.read(BoxName.sosPhonePassenger) == 'sos') { - { - await profileController.updatField( - 'sosPhone', TextInputType.phone); - box.write(BoxName.sosPhonePassenger, - profileController.prfoileData['sosPhone']); - } - } else { - String phoneNumber = box - .read(BoxName.sosPhonePassenger) - .toString(); - // phoneNumber = phoneNumber.replaceAll('0', ''); - var phone = box.read(BoxName.countryCode) == - 'Egypt' - ? '+2${box.read(BoxName.sosPhonePassenger)}' - : '+962${box.read(BoxName.sosPhonePassenger)}'; - controller.sendWhatsapp(phone); - } - }, - icon: const Icon( - FontAwesome.whatsapp, - color: AppColor.greenColor, - ), + SizedBox( + width: Get.width * 0.18, + child: Column( + children: [ + IconButton( + onPressed: () async { + if (box.read(BoxName.sosPhonePassenger) == + null || + box.read(BoxName.sosPhonePassenger) == + 'sos') { + await profileController.updatField( + 'sosPhone', TextInputType.phone); + box.write( + BoxName.sosPhonePassenger, + profileController + .prfoileData['sosPhone']); + } else { + final phoneNumber = box + .read(BoxName.sosPhonePassenger) + .toString(); + final phone = + box.read(BoxName.countryCode) == 'Egypt' + ? '+2$phoneNumber' + : '+962$phoneNumber'; + controller.sendWhatsapp(phone); + } + }, + icon: const Icon(FontAwesome.whatsapp, + color: AppColor.greenColor), + ), + Text('WhatsApp', style: AppStyle.title), + ], ), ), - Container( - decoration: AppStyle.boxDecoration, - width: Get.width * .15, - child: IconButton( - onPressed: () async { - await controller.getTokenForParent(); - }, - icon: const Icon( - Foundation.video, - color: AppColor.blueColor, - ), + SizedBox( + width: Get.width * 0.18, + child: Column( + children: [ + IconButton( + onPressed: () async { + await controller.getTokenForParent(); + }, + icon: const Icon(Foundation.video, + color: AppColor.blueColor), + ), + Text('Video Call', style: AppStyle.title), + ], ), ), ], - ) + ), ], ), ), @@ -317,6 +273,7 @@ class RideBeginPassenger extends StatelessWidget { } } +// Removed the StreamCounter widget as it's not directly part of the RideBeginPassenger UI. class StreamCounter extends StatelessWidget { const StreamCounter({Key? key}) : super(key: key); diff --git a/lib/views/home/map_widget.dart/searching_captain_window.dart b/lib/views/home/map_widget.dart/searching_captain_window.dart index 55ec8d9..86a8ab3 100644 --- a/lib/views/home/map_widget.dart/searching_captain_window.dart +++ b/lib/views/home/map_widget.dart/searching_captain_window.dart @@ -21,35 +21,83 @@ class SearchingCaptainWindow extends StatelessWidget { left: 0, right: 0, child: Container( - decoration: AppStyle.boxDecoration1, - height: Get.height * .25, - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceAround, - // Use Stack for overlapping widgets - children: [ - // Text elements - - SizedBox( - width: Get.width * .7, - child: const LinearProgressIndicator( - minHeight: 6, - backgroundColor: AppColor.yellowColor, - color: AppColor.secondaryColor, - ), + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Theme.of(context) + .scaffoldBackgroundColor, // Use theme color + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(20), + topRight: Radius.circular(20), + ), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.1), + blurRadius: 10, + offset: const Offset(0, -5), ), + ], + ), + child: Column( + mainAxisSize: MainAxisSize.min, // Fit content + children: [ Text( mapPassengerController.driversStatusForSearchWindow, - style: AppStyle.title, + style: AppStyle.title.copyWith( + fontSize: 18, + fontWeight: FontWeight.w600, + ), + textAlign: TextAlign.center, ), - // Text( - // "We are searching for the nearest driver to you".tr, - // style: AppStyle.title, - // ), + const SizedBox(height: 12), Text( - 'please wait till driver accept your order'.tr, - style: AppStyle.title, - ), // Timer logic - _buildTimer(mapPassengerController), + '${'We are searching for the nearest driver to you'.tr}...', // Add ellipsis + style: AppStyle.subtitle.copyWith( + color: Colors.grey.shade600, + ), + textAlign: TextAlign.center, + ), + const SizedBox(height: 16), + SizedBox( + width: Get.width * 0.8, + child: ClipRRect( + borderRadius: BorderRadius.circular(8), + child: LinearProgressIndicator( + minHeight: 8, + backgroundColor: + AppColor.accentColor.withOpacity(0.3), + color: AppColor.primaryColor, + valueColor: const AlwaysStoppedAnimation( + AppColor.primaryColor), + ), + ), + ), + const SizedBox(height: 16), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Icon(Icons.timer_outlined, + size: 16, color: Colors.grey), + const SizedBox(width: 4), + _buildTimer(mapPassengerController), + ], + ), + // const SizedBox(height: 8), + // ElevatedButton( + // onPressed: () { + // // Add logic to cancel the search if needed + // // mapPassengerController.cancelSearch(); + // Get.back(); // Example: go back to the previous screen + // }, + // style: ElevatedButton.styleFrom( + // backgroundColor: Colors.grey.shade300, + // foregroundColor: Colors.black87, + // elevation: 0, + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(8), + // ), + // ), + // child: Text('Cancel Search'.tr), + // ), ], ), ), @@ -60,6 +108,22 @@ class SearchingCaptainWindow extends StatelessWidget { } } +// Widget _buildTimer(MapPassengerController mapPassengerController) { +// return Obx(() { +// final remainingSeconds = mapPassengerController.searchingDuration.value; +// final minutes = (remainingSeconds ~/ 60).toString().padLeft(2, '0'); +// final seconds = (remainingSeconds % 60).toString().padLeft(2, '0'); +// return Text( +// '$minutes:$seconds', +// style: const TextStyle( +// fontSize: 16, +// fontWeight: FontWeight.w500, +// color: Colors.grey, +// ), +// ); +// }); +// } + Widget _buildTimer(MapPassengerController mapPassengerController) { // Start timer at 0 Timer? timer; diff --git a/lib/views/home/profile/order_history.dart b/lib/views/home/profile/order_history.dart index 154f10b..68eb910 100644 --- a/lib/views/home/profile/order_history.dart +++ b/lib/views/home/profile/order_history.dart @@ -1,4 +1,3 @@ -import 'package:SEFER/controller/home/map_passenger_controller.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:SEFER/constant/style.dart'; @@ -84,16 +83,54 @@ class OrderHistory extends StatelessWidget { ), zoom: 12, ), - // bounds: LatLngBounds( - // northeast: LatLng( - // double.parse(rides['end_location'].toString().split(',')[0]), - // double.parse(rides['end_location'].toString().split(',')[1]), - // ), - // southwest: LatLng( - // double.parse(rides['start_location'].toString().split(',')[0]), - // double.parse(rides['start_location'].toString().split(',')[1]), - // ), - // ), + // Dynamically calculate the correct LatLngBounds + onMapCreated: + (GoogleMapController controller) { + final LatLng startLocation = LatLng( + double.parse(rides['start_location'] + .toString() + .split(',')[0]), + double.parse(rides['start_location'] + .toString() + .split(',')[1]), + ); + final LatLng endLocation = LatLng( + double.parse(rides['end_location'] + .toString() + .split(',')[0]), + double.parse(rides['end_location'] + .toString() + .split(',')[1]), + ); + + final LatLngBounds bounds = + LatLngBounds( + northeast: LatLng( + startLocation.latitude > + endLocation.latitude + ? startLocation.latitude + : endLocation.latitude, + startLocation.longitude > + endLocation.longitude + ? startLocation.longitude + : endLocation.longitude, + ), + southwest: LatLng( + startLocation.latitude < + endLocation.latitude + ? startLocation.latitude + : endLocation.latitude, + startLocation.longitude < + endLocation.longitude + ? startLocation.longitude + : endLocation.longitude, + ), + ); + + controller.animateCamera( + CameraUpdate.newLatLngBounds( + bounds, 50)); + }, zoomControlsEnabled: true, polylines: { Polyline( diff --git a/lib/views/widgets/icon_widget_menu.dart b/lib/views/widgets/icon_widget_menu.dart index 604aa40..97ecd55 100644 --- a/lib/views/widgets/icon_widget_menu.dart +++ b/lib/views/widgets/icon_widget_menu.dart @@ -25,7 +25,7 @@ class IconWidgetMenu extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ Container( - width: 50, + width: 40, decoration: const BoxDecoration( color: AppColor.secondaryColor, shape: BoxShape.circle,