جُرد دراور سيرو: 14 مدخلاً للراكب (map_menu_widget) و23 للسائق (drawer_captain). بُني ما له نقطة فعلية على NestJS، والباقي مذكور صراحةً. ## مبنيّ - **المكافآت** (features/rewards): GET /rewards/referrals و /rewards/coupons — كلاهما مُتحقَّق حيّاً. كود الدعوة يُنسخ ويُشارك، وعدّادات دعوتَهم/قيد التأكيد/مدفوعة. يقابل Promos + Invite Driver في سيرو - **شارك التطبيق · قيّم التطبيق · سياسة الخصوصية · تطبيق الطرف الآخر** — أفعال محليّة بلا نقطة خادم (share_plus + url_launcher) - **المساعدة** وُسّعت: أسئلة شائعة قابلة للطيّ · واتساب الدعم · **فحص توافق الجهاز** (نمط سيرو) يفحص ما يُعطّل التطبيق فعلاً: خدمة الموقع وإذنها وإذن الإشعارات — أسباب حقيقية لشكوى «التطبيق لا يعمل» - روابط المتجر والخصوصية والدعم صارت قيم بناء لكل مستأجر في BuildConfig ## غير مبنيّ — ولا نقطة خادم له الشكاوى (R3 في الباكلوج) · الإحصاءات · التحدّيات ولوحة المتصدّرين · مركز الصيانة · جدولي · التأمين الصحي (مؤجَّل بقرار المالك) · الطعام والمواصلات (خارج النطاق، docs/39 §1). بناء واجهة بلا خادم يعني شاشة تكذب على المستخدم. ## سجلّ الإشعارات سيرو يعرض قائمة إشعارات؛ الخادم يوفّر POST /notifications/token فقط بلا نقطة سرد. لم تُبنَ شاشة قائمة على فراغ. flutter analyze نظيف في التطبيقين. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
47 lines
1.2 KiB
Dart
47 lines
1.2 KiB
Dart
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
|
|
import '../../../core/api/api_exception.dart';
|
|
import '../../../core/ui/view_status.dart';
|
|
import '../data/rewards_repository.dart';
|
|
|
|
class RewardsState {
|
|
const RewardsState({
|
|
this.status = ViewStatus.idle,
|
|
this.referrals,
|
|
this.coupons = const [],
|
|
this.error,
|
|
});
|
|
|
|
final ViewStatus status;
|
|
final ReferralSummary? referrals;
|
|
final List<Coupon> coupons;
|
|
final String? error;
|
|
}
|
|
|
|
class RewardsCubit extends Cubit<RewardsState> {
|
|
RewardsCubit(this._repo) : super(const RewardsState());
|
|
|
|
final RewardsRepository _repo;
|
|
|
|
Future<void> load() async {
|
|
emit(const RewardsState(status: ViewStatus.loading));
|
|
try {
|
|
// النداءان متوازيان: لا سبب لانتظار أحدهما الآخر.
|
|
final results = await Future.wait([
|
|
_repo.referrals(),
|
|
_repo.coupons(),
|
|
]);
|
|
if (isClosed) return;
|
|
emit(RewardsState(
|
|
status: ViewStatus.success,
|
|
referrals: results[0] as ReferralSummary,
|
|
coupons: results[1] as List<Coupon>,
|
|
));
|
|
} on ApiException catch (e) {
|
|
if (!isClosed) {
|
|
emit(RewardsState(status: ViewStatus.error, error: e.message));
|
|
}
|
|
}
|
|
}
|
|
}
|