109 lines
3.0 KiB
Dart
109 lines
3.0 KiB
Dart
import 'package:equatable/equatable.dart';
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
import '../data/tariff_repository.dart';
|
|
import '../data/models/quote_model.dart';
|
|
|
|
/// حالة شاشة اختيار فئة الرحلة + السعر.
|
|
class QuoteState extends Equatable {
|
|
final bool loading;
|
|
final QuoteModel? quote;
|
|
final String? selectedClass;
|
|
final String paymentMethod;
|
|
final String? couponCode;
|
|
final String? error;
|
|
|
|
const QuoteState({
|
|
this.loading = false,
|
|
this.quote,
|
|
this.selectedClass,
|
|
this.paymentMethod = 'cash',
|
|
this.couponCode,
|
|
this.error,
|
|
});
|
|
|
|
QuoteState copyWith({
|
|
bool? loading,
|
|
QuoteModel? quote,
|
|
String? selectedClass,
|
|
String? paymentMethod,
|
|
String? couponCode,
|
|
String? error,
|
|
bool clearError = false,
|
|
bool clearCoupon = false,
|
|
}) {
|
|
return QuoteState(
|
|
loading: loading ?? this.loading,
|
|
quote: quote ?? this.quote,
|
|
selectedClass: selectedClass ?? this.selectedClass,
|
|
paymentMethod: paymentMethod ?? this.paymentMethod,
|
|
couponCode: clearCoupon ? null : (couponCode ?? this.couponCode),
|
|
error: clearError ? null : (error ?? this.error),
|
|
);
|
|
}
|
|
|
|
QuoteClassModel? get selectedQuoteClass {
|
|
if (quote == null || selectedClass == null) return null;
|
|
try {
|
|
return quote!.classes.firstWhere((c) => c.vehicleClass == selectedClass);
|
|
} catch (_) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
@override
|
|
List<Object?> get props => [loading, quote, selectedClass, paymentMethod, couponCode, error];
|
|
}
|
|
|
|
/// جلب الأسعار واختيار الفئة.
|
|
class QuoteCubit extends Cubit<QuoteState> {
|
|
final TariffRepository _tariffRepo;
|
|
|
|
QuoteCubit(this._tariffRepo) : super(const QuoteState());
|
|
|
|
Future<void> fetchQuote({
|
|
required double pickupLat,
|
|
required double pickupLng,
|
|
String? pickupAddress,
|
|
required double dropoffLat,
|
|
required double dropoffLng,
|
|
String? dropoffAddress,
|
|
List<Map<String, dynamic>>? stops,
|
|
String? vehicleClass,
|
|
String? scheduledAt,
|
|
}) async {
|
|
emit(state.copyWith(loading: true, clearError: true));
|
|
try {
|
|
final quote = await _tariffRepo.getQuote(
|
|
pickupLat: pickupLat,
|
|
pickupLng: pickupLng,
|
|
pickupAddress: pickupAddress,
|
|
dropoffLat: dropoffLat,
|
|
dropoffLng: dropoffLng,
|
|
dropoffAddress: dropoffAddress,
|
|
vehicleClass: vehicleClass,
|
|
scheduledAt: scheduledAt,
|
|
);
|
|
final firstClass = quote.classes.isNotEmpty ? quote.classes.first.vehicleClass : null;
|
|
emit(state.copyWith(
|
|
loading: false,
|
|
quote: quote,
|
|
selectedClass: firstClass,
|
|
));
|
|
} catch (e) {
|
|
emit(state.copyWith(loading: false, error: e.toString()));
|
|
}
|
|
}
|
|
|
|
void selectClass(String vehicleClass) {
|
|
emit(state.copyWith(selectedClass: vehicleClass));
|
|
}
|
|
|
|
void setPaymentMethod(String method) {
|
|
emit(state.copyWith(paymentMethod: method));
|
|
}
|
|
|
|
void setCouponCode(String? code) {
|
|
emit(state.copyWith(couponCode: code));
|
|
}
|
|
}
|