fix(apps): إصلاحات من أول تجربة حقيقية على الجهاز
## تعذّر حساب الأجرة — الخطأ في التطبيق لا في جدول الكازان الخادم يبذر التعرفة بـ city: 'default' (tenants.service.ts:156) ويستعمل dto.city ?? 'default' عند إنشاء الرحلة، وكنت أرسل city: '' فيرجّع 404 «No active tariff for /economy». تحقّق حيّ: city='default' → total 1.55 JOD ✅ city='' → 404 ❌ city='amman' → 404 ❌ لا تغيير مطلوب على السيرفر. أُضيف AppConfig.defaultCity موثّقاً بالسبب. ## التسعير مرة واحدة لكل الأنواع كان نداء شبكة عند كل ضغطة نوع. صار _priceAll يسعّر كل الأنواع بالتوازي بعد اكتمال المسار — المسافة والمدة ثابتتان والفرق في التعرفة وحدها. الراكب يرى سعر الاقتصادي والمريح معاً تحت كل خيار ويقارن بنظرة، وتبديل النوع بلا نداء. ## الكاميرا لا تتبع الموقع سببان: الموقع يصل قبل إنشاء الخريطة فيضيع التحريك، ولا فحص للإذن/الخدمة قبل getCurrentPosition فيُبتلع الخطأ صامتاً. - _onCreated يلحق بما فات عند جهوز الخريطة - LocationService.ensureReady يفحص الخدمة والإذن أولاً - didChangeAppLifecycleState يعيد المحاولة عند العودة من إعدادات النظام - حالة noLocation تُعرض للمستخدم مع زر إعادة بدل خريطة صامتة ## الخريطة والتنقّل - إطار المسار من حدوده الفعلية مع حشوة سفلية بمقدار ما تغطّيه الورقة - علامتا البداية والنهاية دائرتان ملوّنتان تطابقان ألوان الخط الزمني - زر رجوع في ورقة التأكيد + زر إعادة حساب عند فشل التسعيرة: كان المستخدم يعلق في الشاشة بلا مخرج ## المحفظة — على أي أساس يُشحن POST /wallet/topup شحنٌ تجريبي بلا مزوّد دفع خلفه (الخادم نفسه يصفه كذلك). أُضيف PaymentChannel مشتقّاً من countryPack المستأجر لا من لغة الجهاز: jo → CliQ · sy → سيرياتيل/MTN/شام كاش · eg → PayMob. ويُعرض تنبيه صريح بأن الشحن بلا تحصيل فعلي — إخفاؤه يجعل المستخدم يظنّ أنه دفع. وسحب السائق صار يستعمل القناة المختارة بدل 'cliq' المكتوبة في الكود. flutter analyze نظيف في التطبيقين. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
29f375b122
commit
8976821a93
@@ -37,7 +37,16 @@ enum RidePhase {
|
||||
/// أيّ حقلٍ يلتقط اختيار الخريطة.
|
||||
enum PickTarget { origin, destination }
|
||||
|
||||
enum RideError { none, noDrivers, quoteFailed, routeFailed, requestFailed }
|
||||
enum RideError {
|
||||
none,
|
||||
noDrivers,
|
||||
quoteFailed,
|
||||
routeFailed,
|
||||
requestFailed,
|
||||
|
||||
/// الموقع مرفوض أو الخدمة مطفأة — بلا موقع لا خريطة مفيدة.
|
||||
noLocation,
|
||||
}
|
||||
|
||||
class RideState extends Equatable {
|
||||
const RideState({
|
||||
@@ -51,6 +60,7 @@ class RideState extends Equatable {
|
||||
this.selectedRideType,
|
||||
this.route,
|
||||
this.quote,
|
||||
this.quotes = const {},
|
||||
this.trip,
|
||||
this.driverLocation,
|
||||
this.searchResults = const [],
|
||||
@@ -74,8 +84,17 @@ class RideState extends Equatable {
|
||||
final RideType? selectedRideType;
|
||||
|
||||
final RouteInfo? route;
|
||||
|
||||
/// تسعيرة النوع المختار — مشتقّة من [quotes] للراحة.
|
||||
final FareQuote? quote;
|
||||
|
||||
/// **كل الأنواع مسعَّرة دفعةً واحدة** بمفتاح `RideType.code`.
|
||||
///
|
||||
/// الراكب يرى أسعار الاقتصادي والمريح والعائلي معاً فيقارن ويقرّر — بدل
|
||||
/// نداء شبكة عند كل ضغطة نوع. المسافة والمدة ثابتتان للمسار، فالنداءات
|
||||
/// متوازية ومرة واحدة.
|
||||
final Map<String, FareQuote> quotes;
|
||||
|
||||
final Trip? trip;
|
||||
|
||||
/// موقع السائق الحيّ من `driver:location`.
|
||||
@@ -96,6 +115,9 @@ class RideState extends Equatable {
|
||||
/// كود الخصم — يُقيَّم على الخادم عند الطلب لا في التطبيق.
|
||||
final String couponCode;
|
||||
|
||||
/// تسعيرة نوعٍ بعينه — لعرض السعر تحت كل خيار.
|
||||
FareQuote? quoteFor(String code) => quotes[code];
|
||||
|
||||
bool get canConfirm =>
|
||||
origin != null &&
|
||||
destination != null &&
|
||||
@@ -113,6 +135,7 @@ class RideState extends Equatable {
|
||||
RideType? selectedRideType,
|
||||
RouteInfo? route,
|
||||
FareQuote? quote,
|
||||
Map<String, FareQuote>? quotes,
|
||||
Trip? trip,
|
||||
GeoPoint? driverLocation,
|
||||
List<Place>? searchResults,
|
||||
@@ -140,6 +163,7 @@ class RideState extends Equatable {
|
||||
selectedRideType: selectedRideType ?? this.selectedRideType,
|
||||
route: clearRoute ? null : (route ?? this.route),
|
||||
quote: clearRoute ? null : (quote ?? this.quote),
|
||||
quotes: clearRoute ? const {} : (quotes ?? this.quotes),
|
||||
trip: clearTrip ? null : (trip ?? this.trip),
|
||||
driverLocation: driverLocation ?? this.driverLocation,
|
||||
searchResults: searchResults ?? this.searchResults,
|
||||
@@ -164,6 +188,7 @@ class RideState extends Equatable {
|
||||
selectedRideType,
|
||||
route,
|
||||
quote,
|
||||
quotes,
|
||||
trip,
|
||||
driverLocation,
|
||||
searchResults,
|
||||
|
||||
Reference in New Issue
Block a user