forked from eatvio/eatvio_app
175 lines
6.6 KiB
Dart
175 lines
6.6 KiB
Dart
import 'package:eatvio_app/core/theme/custom_text_style.dart';
|
|
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
|
import 'package:eatvio_app/core/utils/toasts.dart';
|
|
import 'package:eatvio_app/core/widgets/custom_outlined_button.dart';
|
|
import 'package:eatvio_app/features/registration/presentation/bloc/verify_email_cubit/verify_email_cubit.dart';
|
|
import 'package:eatvio_app/features/registration/presentation/bloc/verify_email_cubit/verify_email_state.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
|
|
class ChangeEmailDialog extends StatefulWidget {
|
|
final String currentEmail;
|
|
final VerifyEmailCubit verifyEmailCubit;
|
|
|
|
const ChangeEmailDialog({super.key, required this.currentEmail, required this.verifyEmailCubit});
|
|
|
|
@override
|
|
State<ChangeEmailDialog> createState() => _ChangeEmailDialogState();
|
|
}
|
|
|
|
class _ChangeEmailDialogState extends State<ChangeEmailDialog> {
|
|
final TextEditingController _emailController = TextEditingController();
|
|
final FocusNode _emailFocusNode = FocusNode();
|
|
bool _isLoading = false;
|
|
String? _errorText;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_emailController.text = widget.currentEmail;
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_emailController.dispose();
|
|
_emailFocusNode.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
bool _isValidEmail(String email) {
|
|
return RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(email);
|
|
}
|
|
|
|
void _validateEmail() {
|
|
final email = _emailController.text.trim();
|
|
if (email.isEmpty) {
|
|
setState(() {
|
|
_errorText = 'Введите email';
|
|
});
|
|
} else if (!_isValidEmail(email)) {
|
|
setState(() {
|
|
_errorText = 'Введите корректный email';
|
|
});
|
|
} else if (email == widget.currentEmail) {
|
|
setState(() {
|
|
_errorText = 'Новый email должен отличаться от текущего';
|
|
});
|
|
} else {
|
|
setState(() {
|
|
_errorText = null;
|
|
});
|
|
}
|
|
}
|
|
|
|
Future<void> _changeEmail() async {
|
|
_validateEmail();
|
|
if (_errorText != null) return;
|
|
|
|
setState(() {
|
|
_isLoading = true;
|
|
});
|
|
|
|
try {
|
|
await widget.verifyEmailCubit.changeEmail(_emailController.text.trim());
|
|
// Диалог закроется автоматически при успешной смене email через основной экран
|
|
} catch (e) {
|
|
if (mounted) {
|
|
showErrorToast('Ошибка при смене email. Попробуйте снова.');
|
|
setState(() {
|
|
_isLoading = false;
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return BlocProvider.value(
|
|
value: widget.verifyEmailCubit,
|
|
child: BlocListener<VerifyEmailCubit, VerifyEmailState>(
|
|
listener: (context, state) {
|
|
if (state is VerifyEmailStateChangeEmailSuccess) {
|
|
Navigator.of(context).pop(); // Закрываем диалог при успешной смене
|
|
} else if (state is VerifyEmailStateChangeEmailError) {
|
|
setState(() {
|
|
_isLoading = false;
|
|
});
|
|
}
|
|
},
|
|
child: Dialog(
|
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(24.0),
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text('Сменить email', style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black)),
|
|
const SizedBox(height: 16),
|
|
Text('Введите новый email для получения кода подтверждения', style: TextStyles.textSMedium.copyWith(color: appTheme.gray)),
|
|
const SizedBox(height: 20),
|
|
TextField(
|
|
controller: _emailController,
|
|
focusNode: _emailFocusNode,
|
|
keyboardType: TextInputType.emailAddress,
|
|
decoration: InputDecoration(
|
|
hintText: 'Введите новый email',
|
|
hintStyle: TextStyles.textSMedium.copyWith(color: appTheme.gray),
|
|
border: OutlineInputBorder(
|
|
borderRadius: BorderRadius.circular(12),
|
|
borderSide: BorderSide(color: appTheme.gray),
|
|
),
|
|
focusedBorder: OutlineInputBorder(
|
|
borderRadius: BorderRadius.circular(12),
|
|
borderSide: BorderSide(color: appTheme.blueA400),
|
|
),
|
|
errorBorder: OutlineInputBorder(
|
|
borderRadius: BorderRadius.circular(12),
|
|
borderSide: BorderSide(color: appTheme.red),
|
|
),
|
|
errorText: _errorText,
|
|
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
|
|
),
|
|
onChanged: (_) => _validateEmail(),
|
|
onSubmitted: (_) => _changeEmail(),
|
|
),
|
|
const SizedBox(height: 24),
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: CustomOutlinedButton(
|
|
text: 'Отмена',
|
|
height: 52,
|
|
buttonTextStyle: TextStyles.textMSemibold.copyWith(color: appTheme.black),
|
|
buttonStyle: ButtonStyle(
|
|
side: const WidgetStatePropertyAll(BorderSide.none),
|
|
backgroundColor: WidgetStatePropertyAll(appTheme.lightGray0),
|
|
),
|
|
onPressed: () => Navigator.of(context).pop(),
|
|
),
|
|
),
|
|
const SizedBox(width: 12),
|
|
Expanded(
|
|
child: CustomOutlinedButton(
|
|
text: _isLoading ? 'Отправка...' : 'Сменить',
|
|
height: 52,
|
|
isDisabled: _isLoading,
|
|
buttonTextStyle: TextStyles.textMSemibold.copyWith(color: appTheme.whiteA700),
|
|
buttonStyle: ButtonStyle(
|
|
side: const WidgetStatePropertyAll(BorderSide.none),
|
|
backgroundColor: WidgetStatePropertyAll(_isLoading ? appTheme.gray : appTheme.blueA400),
|
|
),
|
|
onPressed: _isLoading ? null : _changeEmail,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|