From 044d86e710934e9dfa7fc4138938123d94016b84 Mon Sep 17 00:00:00 2001 From: mso7nueh Date: Thu, 29 Jan 2026 15:49:13 +0300 Subject: [PATCH] fix mask formatter in phone --- lib/core/utils/validation_utils.dart | 15 +++++++++++++++ .../pages/register_via_social_screen.dart | 7 ++++--- .../registration_v2/cubit/registration_cubit.dart | 3 ++- .../presentation/widgets/first_step_content.dart | 7 ++++++- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/lib/core/utils/validation_utils.dart b/lib/core/utils/validation_utils.dart index 1add6cda..0e9bbccd 100644 --- a/lib/core/utils/validation_utils.dart +++ b/lib/core/utils/validation_utils.dart @@ -16,6 +16,21 @@ class ValidationUtils { return regex.hasMatch(phone); } + /// Нормализация номера телефона (+79991234455) + static String normalizePhone(String phone) { + if (phone.isEmpty) return ''; + final digits = phone.replaceAll(RegExp(r'[^\d]'), ''); + if (digits.isEmpty) return ''; + + String normalized = digits; + if (digits.startsWith('8')) { + normalized = '7${digits.substring(1)}'; + } else if (digits.length == 10) { + normalized = '7$digits'; + } + return '+$normalized'; + } + /// Валидация URL static bool isValidUrl(String url) { if (url.isEmpty) return false; diff --git a/lib/features/auth/presentation/pages/register_via_social_screen.dart b/lib/features/auth/presentation/pages/register_via_social_screen.dart index 5ee5233a..1b27237f 100644 --- a/lib/features/auth/presentation/pages/register_via_social_screen.dart +++ b/lib/features/auth/presentation/pages/register_via_social_screen.dart @@ -16,6 +16,7 @@ import 'package:eatvio_app/features/create_diet/presentation/widgets/error_widge import 'package:eatvio_app/features/notifications/presentation/notifications_cubit/notifications_cubit.dart'; import 'package:eatvio_app/core/firebase_api.dart'; import 'package:eatvio_app/core/utils/toasts.dart'; +import 'package:eatvio_app/core/utils/validation_utils.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -538,7 +539,7 @@ class _RegisterViaSocialScreenState extends State { if (hasErrorWeightOrHeightError) return; // Очищаем номер телефона от маски для отправки - final cleanPhone = phoneController.text.replaceAll(RegExp(r'[^\d+]'), ''); + final cleanPhone = ValidationUtils.normalizePhone(phoneController.text); if (clientID == null) return; // Вызываем OAuth регистрацию @@ -615,7 +616,7 @@ class _RegisterViaSocialScreenState extends State { final oauthCubit = CubitRegistrations.sl(); // Всегда передаем и email и phone final String email = emailController.text; - final String phone = phoneController.text.replaceAll(RegExp(r'[^\d+]'), ''); + final String phone = ValidationUtils.normalizePhone(phoneController.text); final response = await oauthCubit.requestOAuthVerification(email: email, phone: phone); @@ -726,7 +727,7 @@ class _RegisterViaSocialScreenState extends State { // Всегда передаем и email и phone (полный набор данных от провайдера) // Используем данные из формы, если они есть, иначе из authResult final String email = emailController.text.isNotEmpty ? emailController.text : (authResult.email ?? ''); - final String phone = phoneController.text.isNotEmpty ? phoneController.text.replaceAll(RegExp(r'[^\d+]'), '') : (authResult.phone ?? ''); + final String phone = phoneController.text.isNotEmpty ? ValidationUtils.normalizePhone(phoneController.text) : ValidationUtils.normalizePhone(authResult.phone ?? ''); // Проверяем, что данные есть if (email.isEmpty && phone.isEmpty) { diff --git a/lib/features/registration_v2/cubit/registration_cubit.dart b/lib/features/registration_v2/cubit/registration_cubit.dart index 49d4eabc..cfc72b4b 100644 --- a/lib/features/registration_v2/cubit/registration_cubit.dart +++ b/lib/features/registration_v2/cubit/registration_cubit.dart @@ -3,6 +3,7 @@ import 'dart:developer'; import 'package:dio/dio.dart'; import 'package:eatvio_app/core/token_storage.dart'; import 'package:eatvio_app/core/utils/date_time_utils.dart'; +import 'package:eatvio_app/core/utils/validation_utils.dart'; import 'package:eatvio_app/features/registration_v2/cubit/registration_state.dart'; import 'package:eatvio_app/features/registration_v2/models/registration_model.dart'; import 'package:eatvio_app/features/registration_v2/repositories/registration_repository_v2.dart'; @@ -180,7 +181,7 @@ class RegistrationCubitV2 extends Cubit { firstName: state.firstName, lastName: state.lastName, email: state.email, - phone: state.phone, + phone: ValidationUtils.normalizePhone(state.phone), gender: state.gender, password: password, confirmPassword: password, diff --git a/lib/features/registration_v2/presentation/widgets/first_step_content.dart b/lib/features/registration_v2/presentation/widgets/first_step_content.dart index 78244da8..dbb22951 100644 --- a/lib/features/registration_v2/presentation/widgets/first_step_content.dart +++ b/lib/features/registration_v2/presentation/widgets/first_step_content.dart @@ -21,6 +21,7 @@ class FirstStepContent extends StatefulWidget { class _FirstStepContentState extends State { final maskFormatterForBirthday = MaskTextInputFormatter(mask: '##.##.####', filter: {"#": RegExp(r'[0-9]')}, type: MaskAutoCompletionType.lazy); + final maskFormatter = MaskTextInputFormatter(mask: '+7 (###) ### ## ##', filter: {"#": RegExp(r'[0-9]')}, type: MaskAutoCompletionType.lazy); final firstNameController = TextEditingController(); @@ -37,7 +38,10 @@ class _FirstStepContentState extends State { firstNameController.text = context.read().state.firstName; lastNameController.text = context.read().state.lastName; emailController.text = context.read().state.email; - phoneController.text = context.read().state.phone; + final phone = context.read().state.phone; + if (phone.isNotEmpty) { + phoneController.text = maskFormatter.maskText(phone); + } dateController.text = context.read().state.birthday?.format('dd.MM.yyyy') ?? ''; } @@ -113,6 +117,7 @@ class _FirstStepContentState extends State { hintText: '+7 (999) 999 99 99', controller: phoneController, hasError: !state.isPhoneValid, + inputFormatters: [maskFormatter], keyboardType: TextInputType.phone, onChanged: (val) { context.read().setPhone(val);