# 39 — جرد شاشات سيرو: المرجع البصري والسلوكي الغرض: هذا **ما نبني عليه الشكل والترتيب** في `rider_new` و`driver_new` (م0.3 من `docs/37`). المصدر: `~/development/App/Siro/siro_rider` و`siro_driver`. > **قاعدة الاستخدام**: هذا الملف يجيب على «ما هي الشاشة، وما ترتيب خطواتها، > وأي حالة حافة عولجت ميدانياً». **لا يُنسخ ملف دارت واحد من سيرو.** > شكل الواجهة يُعاد بناؤه على `docs/26` بجودة أعلى، والعقد من `docs/38`. --- ## 1. المخزون — الحجم الحقيقي | | شاشات/ويدجت | ملاحظة | |---|---|---| | `siro_rider/lib/views` | 89 ملف | يشمل الطعام والنقل العام | | `siro_driver/lib/views` | 113 ملف | يشمل التوصيل والتلعيب والإحصاءات | **ليس كله في النطاق.** خارج نطاق `docs/37` تماماً: `food/`, `food_delivery/`, `transit/`, `gamification/`, `assurance_health_page`, `siro_prime_page`, `android_bot`. هذي تُقرأ لاحقاً عند وحدات `docs/33` المدفوعة، لا الآن. **داخل النطاق** (م1–م6): المصادقة · الخريطة وطلب الرحلة · مسار الرحلة · المحفظة · الدراور والملف · الإشعارات · التقييم. --- ## 2. المصادقة — مرجع م3 ### التسلسل في سيرو (متطابق في التطبيقين) ``` موافقة الشروط → إذن الموقع → رقم الهاتف → OTP → [تسجيل] → الرئيسية ``` بوابتان **قبل** أي حقل إدخال، وكل واحدة شاشة كاملة لا حوار: 1. **صفحة الموافقة** (`_buildAgreementPage`): نصّ الاتفاقية بـHTML من الخادم، مربّع اختيار، وزر متابعة **معطّل حتى يُؤشَّر**. تُحفظ (`BoxName.agreeTerms == 'agreed'`) ولا تتكرر. 2. **صفحة إذن الموقع**: تطلب الإذن، ومعها زر `openAppSettings()` للحالة التي يرفض فيها المستخدم نهائياً. تطبيق السائق يراقب دورة حياة التطبيق (`WidgetsBindingObserver` + `didChangeAppLifecycleState`) ليعيد الفحص عند **العودة من إعدادات النظام** — بلا هذا تبقى الشاشة عالقة. حالة حافة حقيقية لازم تُنقل. ### شاشة الهاتف - `IntlPhoneField` مع مفتاح دولة افتراضي من `BoxName.countryCode`. - تحقّقات مطبّقة: فارغ · **يبدأ بصفر → رفض** («أدخل بلا الصفر») · أقصر من 10. - الرقم يُرسل بلا `+`. ### شاشة الـOTP - **3 خانات** في سيرو، حقل واحد بتباعد حروف كبير + ثلاث نقاط تقدّم متحرّكة. - ⚠️ **تريبز يستخدم 4 خانات** (`docs/38`). الشكل يُقلَّد، الطول لا. - ⚠️ **لا يوجد عدّاد إعادة إرسال ولا زر «إعادة الإرسال» في سيرو.** هذه **فجوة، لا مرجع**: تريبز يحدّ `send-otp` بـ3 طلبات/5 دقائق، فبلا عدّاد تنازلي يُحظر المستخدم بثلاث ضغطات. **لازم نضيفها.** ### شاشة التسجيل الاسم الأول · الأخير · البريد. ⚠️ عقد تريبز يقبل `{ name, language }` فقط (`PATCH /users/me`) — حقل اسم واحد. لا تُنقل الحقول كما هي. ### فروق تطبيق السائق مسار إضافي بعد الدخول: `registration_view` (تسجيل السائق) → `pending_driver_page` (شاشة «قيد المراجعة») → `camera_lisence_page` / `text_scanner` / `passportimage` (تصوير الوثائق) → `cars_inserting_page`. يقابلها في تريبز: `/drivers/apply` → `/drivers/profile` → `/drivers/documents` → `/vehicles`، **ثم إعادة دخول إجبارية** لأن الدور يتغيّر بعد الاعتماد (مصيدة `docs/38` §5). ### ما لا يُنقل من طبقة مصادقة سيرو `login_controller.dart` فيه JWT مزدوج (توكن عام + `walletJwt` منفصل)، وقفل تزامن ساكن، وعدّاد إخفاقات، وفكّ base64 يدوي للـpayload. **هذا تعقيد مفروض من باك إند PHP**، وتريبز عنده `access_token`/`refresh_token` واحد. لا يُنقل. المُنقَل هو الفكرة الصالحة: **تجديد واحد متزامن لا يتضاعف عند تعدد الطلبات**. --- ## 3. الخريطة وطلب الرحلة — مرجع م4 أنضج جزء في سيرو، وأدقّ ما نأخذه منه. الوحدة: `views/home/route_planner/` (10 ملفات، 1,928 سطراً) + `views/home/map_widget.dart/`. ### البنية: خريطة ثابتة + ورقة سفلية بثلاث حالات 1. **مطوية** (`_Collapsed`) — بطاقة «إلى أين؟» فقط. 2. **موسّعة** (`_Expanded`) — المخطّط الكامل. 3. **اختيار من الخريطة** (`RpMapPickOverlay`) — الورقة تنزوي، ودبّوس ثابت في المنتصف (`rp_center_pin`) والخريطة تتحرك تحته. النمط الصحيح: **المستخدم يحرّك الخريطة لا الدبّوس.** ### ترتيب المخطّط الموسّع (من أعلى لأسفل) ترويسة → **مبدّل نوع الطلب** (لنفسي ⇄ لشخص آخر) → **الخط الزمني للمسار** (المصدر · محطات وسيطة · الوجهة) → **وصول سريع** (المنزل/العمل) → **متقدّم**. - المصدر افتراضياً = الموقع الحالي، وقابل للتغيير من الخريطة. - عند «لشخص آخر» يتبدّل حقل المصدر فوراً (`rp_sheet.dart:509`). - **المحطات الوسيطة** صفوف قابلة للإضافة/الحذف — يقابلها `stops[]` في `POST /trips` (`docs/38` §4). موجودة في الطرفين. - المفضّلات (`rp_favorites`) والبحث (`rp_search_dialog` + `rp_search_results`). ### نافذة البحث عن سائق (`searching_captain_window`) - أنيميشن رادار (دورة ثانيتين) + نصّ الحالة من الكنترولر + مؤشّر دوّار. - **لا مقبض سحب** — لا تُغلق بالسحب، **فقط بزر «إلغاء البحث»**. قرار تصميمي صحيح يُنقل: المستخدم لا يزيح شاشة البحث بالخطأ. - الويدجت «غبي» بلا منطق؛ المؤقّت في الكنترولر هو من يقرر متى يعرض حوار زيادة الأجرة. **يقابل مباشرةً** مصيدة `docs/38` §4: `expired`/`no_drivers` قد لا يصلان من الخادم → **المهلة المحليّة إلزامية**. سيرو عالجها؛ نكرّرها. ### بطاقة الرحلة الجارية (`apply_order_widget`, 871 سطراً) ترويسة مضغوطة · بطاقة معلومات · **شارة السائق** · **لوحة مركبة مرسومة** · أيقونة سيارة متحرّكة · صف أزرار · حقل رسالة مخصّصة · مؤشّرا «وصل السائق وينتظر ن دقيقة» و«الوقت المتبقّي للوصول». هذي المكوّنات هي ما يجعل الشاشة تبدو احترافية — تُعاد بناؤها في `packages/tripz_ui`، لا تُنسخ. ### شاشات مساندة `payment_method_page` · `cash_confirm_bottom_page` · `cancel_raide_page` (أسباب الإلغاء) · `ride_begin_passenger` · `car_details_widget_to_go` · `trip_monitor` + `trip_link_monitor` (مشاركة رابط تتبّع) · `voice_call_bottom_sheet` (WebRTC — يقابل `call:*` في `docs/38` §9). ### شاشة السائق (`order_request_page`, 468 سطراً) خريطة → **كبسولة «الوصول للراكب»** → بطاقة سفلية: `الراكب + السعر` → `شريط معلومات (المسافة/المدة)` → `العناوين` → `الأزرار`. - **حالة تحميل صريحة** إن وصل العرض بلا بيانات كاملة — لا شاشة فارغة. - `order_over_lay.dart` (847 سطراً) = العرض المنبثق فوق أي شاشة. يقابل `trip:offer` و`trip:offer_taken` في `docs/38` §9. - ⚠️ شارة `driverEarningsExtra` تعتمد حقولاً من `add_ride.php` (باك إند PHP) **غير موجودة في عقد NestJS** — تُسقط أو يُضاف لها حقل في الخادم. مثال حيّ على أن سيرو ليس مطابقاً للعقد. --- ## 4. المحفظة — مرجع م5 | الراكب | السائق | |---|---| | `passenger_wallet` · `payment_history_passenger_page` · `cliq_payment_sheet` · `payment_screen_cliq/mtn/sham` | `walet_captain` · `pay_out_screen` · `weekly_payment_page` · `transfer_budget_page` · `points_captain` · `ecash` · `bank_account_egypt` | محفظة السائق مقسّمة لويدجت جاهزة (`balance_card` · `financial_summary_card` · `quick_actions` · `transaction_preview_item`) — تفكيك جيد يُحتذى. ⚠️ **مصيدتان**: 1. سيرو يخلط محفظة الراكب والسائق في تصميم واحد. تريبز يفصلهما (التزام مقابل إيراد) — لا تُوحَّد الشاشة. 2. `pay_out_screen` في سيرو **خطوة واحدة**؛ تريبز **خطوتان** مع OTP (`docs/38` §6). الشاشة تُعاد تصميمها لا تُقلَّد. --- ## 5. الدراور والملف والإشعارات — مرجع م6 **الراكب**: `drawer_menu_page` · `passenger_profile_page` · `order_history` · `setting_page` · `languages` · `about_page` · `contact_us` · `frequentlyQuestionsPage` · `share_app_page` · `complaint_page` · `promos_passenger_page` · `taarif_page` · `notification_page` · `rate_captain` + `rating_driver_bottom`. **السائق**: `drawer_captain` · `bottom_bar` (تنقّل سفلي — الراكب بلا) · `profile_captain` · `captains_cars` · `history_captain` + `history_details_page` · `settings_captain` · `behavior_page` · `feed_back_page` · `help_captain` + `help_details_replay_page` · `available_rides_page` · `statistics_dashboard` (+6 ويدجت رسوم) · `rate_passenger` · `ride_calculate_driver` · `sos_connect` (استغاثة). **شاشة التقييم مهمة معمارياً**: تُفرض عند فتح التطبيق عبر `GET /trips/rating/pending` (`docs/38` §7) — تُبنى في م5 لا م6. --- ## 6. الويدجت المشتركة — مدخل `packages/tripz_ui` الملفات نفسها **مكرّرة حرفياً** في التطبيقين: `circle_container` · `elevated_btn` · `error_snakbar` · `icon_widget_menu` · `my_circular_indicator_timer` · `my_scafold` · `my_textField` · `mycircular` · `mydialoug` · `voice_call_bottom_sheet`. **هذا بالضبط ما تحلّه `packages/tripz_ui`** (م2.11): ازدواج مؤكَّد في سيرو، لا يتكرر عندنا. --- ## 7. ملاحظات أداء — مادة قائمة الممنوعات (م2.12) من قراءة سيرو، هذي أنماط تُتجنّب في `*_new`: - `Get.put()` داخل `build()` (`login_page.dart:27`) — حقن عند كل إعادة بناء. - ملفات ويدجت تتجاوز 800 سطر (`apply_order_widget` 871 · `order_over_lay` 847 · `home_captin` 840) — تفكّك. - `GetBuilder` يلفّ الشاشة كاملة → إعادة بناء الشجرة كلها عند أي تحديث. البديل: `BlocSelector`/`buildWhen` على أصغر جزء. - منطق داخل الويدجت. النمط الصحيح موجود في سيرو نفسه (`searching_captain_window` «غبي» والمؤقّت في الكنترولر) — يُعمَّم. > قائمة الممنوعات النهائية تُستكمل في م2 بعد تشخيص `*-archive-cubit` نفسه — > فسبب الأداء المرفوض هناك، لا هنا.