Files
be_happy_public/lib/presentation/screens/add_card_screen.dart

233 lines
12 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:be_happy/presentation/viewmodel/payment_methods_bloc.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart';
import '../../core/app_colors.dart';
import '../components/custom_app_bar.dart';
import '../components/card_input_field.dart'; // ← новый импорт
import '../components/utils/card_formatter.dart';
import '../event/payment_methods_event.dart';
import '../viewmodel/add_card_bloc.dart';
import '../event/add_card_event.dart';
import '../state/add_card_state.dart';
class AddCardScreen extends StatelessWidget {
const AddCardScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: BlocListener<AddCardBloc, AddCardState>(
listenWhen: (previous, current) =>
previous.status != current.status &&
current.status == AddCardStatus.success,
listener: (context, state) {
context.pop();
},
child: Container(
decoration: const BoxDecoration(gradient: AppColors.phoneScreenBg),
child: SafeArea(
child: Column(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
children: [
const SizedBox(height: 16),
const CustomAppBar(title: 'Добавление карты'),
const SizedBox(height: 24),
Container(
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: const Color(0xFF0A0F2E),
borderRadius: BorderRadius.circular(20),
),
child: Column(
children: [
BlocBuilder<AddCardBloc, AddCardState>(
builder: (context, state) {
return CardInputField(
hintText: '0000 0000 0000 0000',
icon: Icons.credit_card,
keyboardType: TextInputType.number,
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
LengthLimitingTextInputFormatter(16),
CardNumberFormatter(),
],
letterSpacing: 2,
onChanged: (value) {
final cleanValue = value.replaceAll(' ', '');
context.read<AddCardBloc>().add(CardNumberChanged(cleanValue));
},
);
},
),
const SizedBox(height: 16),
Row(
children: [
Expanded(
child: BlocBuilder<AddCardBloc, AddCardState>(
builder: (context, state) {
return CardInputField(
hintText: 'MM/YY',
keyboardType: TextInputType.number,
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
LengthLimitingTextInputFormatter(4),
CardMonthInputFormatter(),
],
onChanged: (value) {
final cleanValue = value.replaceAll('/', '');
context.read<AddCardBloc>().add(ExpiryDateChanged(cleanValue));
},
);
},
),
),
const SizedBox(width: 12),
Expanded(
child: BlocBuilder<
AddCardBloc,
AddCardState>(
builder: (context, state) {
return CardInputField(
hintText: 'CVV',
obscureText: true,
keyboardType: TextInputType.number,
inputFormatters: [
FilteringTextInputFormatter
.digitsOnly,
LengthLimitingTextInputFormatter(
3),
],
onChanged: (value) {
context.read<AddCardBloc>().add(
CvvChanged(value));
},
);
},
),
),
],
),
const SizedBox(height: 16),
BlocBuilder<AddCardBloc, AddCardState>(
builder: (context, state) {
return CardInputField(
hintText: 'Имя и фамилия на карте',
keyboardType: TextInputType.text,
textCapitalization: TextCapitalization
.words,
onChanged: (value) {
context.read<AddCardBloc>().add(
CardHolderChanged(value));
},
);
},
),
const SizedBox(height: 20),
BlocBuilder<AddCardBloc, AddCardState>(
builder: (context, state) {
return Container(
height: 46,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24),
color: Colors.white.withOpacity(0.15),
),
child: Material(
color: Colors.transparent,
child: InkWell(
onTap: state.isFormValid
? () => {
context.read<AddCardBloc>().add(
AddCardSubmitted()),
context.read<PaymentMethodsBloc>()..add(PaymentMethodsStarted()),
context.pop()
}
: null,
borderRadius: BorderRadius.circular(
24),
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment
.center,
children: [
Icon(
Icons.add,
color: state.isFormValid
? const Color(0xFF66E3C4)
: Colors.white
.withOpacity(0.3),
size: 20,
),
const SizedBox(width: 8),
Text(
'Добавить карту',
style: TextStyle(
color: state.isFormValid
? Colors.white
: Colors.white
.withOpacity(0.3),
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
],
),
),
),
),
);
},
),
],
),
),
],
),
),
),
Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(
horizontal: 20, vertical: 24),
child: Column(
children: [
const Text(
'Мы не сохраняем данные карты у себя. Оплата происходит '
'через сертифицированный провайдер Беларуси bePaid. '
'Платежная страница системы bePaid отвечает требованиям '
'безопасности передачи данных PCI DSS Level I. '
'Все конфиденциальные данные хранятся в зашифрованном виде.',
style: TextStyle(
color: Colors.white38,
fontSize: 11,
height: 1.5,
),
textAlign: TextAlign.justify,
),
const SizedBox(height: 24),
],
),
),
],
),
),
),
)
);
}
}