new project stable version

This commit is contained in:
2026-05-10 19:11:31 +03:00
commit 3616f84556
391 changed files with 23857 additions and 0 deletions

View File

@@ -0,0 +1,112 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../domain/usecase/add_payment_card_usecase.dart';
import '../event/add_card_event.dart';
import '../state/add_card_state.dart';
// 🔹 Импорты для Result и Failure
import '../../core/result.dart';
import '../../core/failures.dart';
class AddCardBloc extends Bloc<AddCardEvent, AddCardState> {
final AddPaymentCardUsecase addPaymentCardUsecase;
AddCardBloc(this.addPaymentCardUsecase) : super(const AddCardState()) {
on<CardNumberChanged>(_onCardNumberChanged);
on<ExpiryDateChanged>(_onExpiryDateChanged);
on<CvvChanged>(_onCvvChanged);
on<CardHolderChanged>(_onCardHolderChanged);
on<AddCardSubmitted>(_onAddCardSubmitted);
}
void _onCardNumberChanged(CardNumberChanged event, Emitter<AddCardState> emit) {
final formatted = _formatCardNumber(event.cardNumber);
emit(state.copyWith(cardNumber: formatted));
}
void _onExpiryDateChanged(ExpiryDateChanged event, Emitter<AddCardState> emit) {
final formatted = _formatExpiryDate(event.expiryDate);
emit(state.copyWith(expiryDate: formatted));
}
void _onCvvChanged(CvvChanged event, Emitter<AddCardState> emit) {
final formatted = event.cvv.replaceAll(RegExp(r'\D'), '').substring(0, 3);
emit(state.copyWith(cvv: formatted));
}
void _onCardHolderChanged(CardHolderChanged event, Emitter<AddCardState> emit) {
emit(state.copyWith(cardHolder: event.cardHolder));
}
Future<void> _onAddCardSubmitted(AddCardSubmitted event, Emitter<AddCardState> emit) async {
if (state.cardNumber.isEmpty || state.expiryDate.isEmpty) return;
emit(state.copyWith(status: AddCardStatus.loading));
final expiryParts = state.expiryDate.split('/'); // Используем state
if (expiryParts.length != 2) {
emit(state.copyWith(
status: AddCardStatus.failure,
errorMessage: 'Неверный формат даты',
));
return;
}
final result = await addPaymentCardUsecase(
cardNumber: state.cardNumber.replaceAll(' ', ''),
expiryMonth: expiryParts[0],
expiryYear: expiryParts[1],
cardHolder: state.cardHolder.trim(),
cvv: state.cvv,
);
if (result is Success) {
emit(state.copyWith(status: AddCardStatus.success));
} else if (result is Failure) {
final failure = result.failure;
String errorMessage = 'Ошибка добавления карты';
if (failure is AuthFailure) {
errorMessage = 'Неверные данные карты';
} else if (failure is AuthBlockFailure) {
errorMessage = 'Доступ заблокирован';
} else if (failure is UnknownFailure) {
errorMessage = failure.message ?? 'Неизвестная ошибка';
}
emit(state.copyWith(
status: AddCardStatus.failure,
errorMessage: errorMessage,
));
}
}
String _formatCardNumber(String value) {
final cleaned = value.replaceAll(RegExp(r'\D'), '');
final limited = cleaned.substring(0, cleaned.length > 16 ? 16 : cleaned.length);
String formatted = '';
for (int i = 0; i < limited.length; i++) {
if (i > 0 && i % 4 == 0) {
formatted += ' ';
}
formatted += limited[i];
}
return formatted;
}
String _formatExpiryDate(String value) {
final cleaned = value.replaceAll(RegExp(r'\D'), '');
if (cleaned.isEmpty) return '';
if (cleaned.length <= 2) {
return cleaned;
}
final month = cleaned.substring(0, 2);
final year = cleaned.substring(2, cleaned.length > 4 ? 4 : cleaned.length);
return '$month/$year';
}
}