feat(registration): add phone

This commit is contained in:
Alex
2024-12-18 13:34:47 +03:00
parent 12a24e6ead
commit f0cdb73496
8 changed files with 151 additions and 62 deletions

View File

@@ -1,5 +1,6 @@
import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:eatvio_app/core/const.dart';
import 'package:eatvio_app/core/locator_service.dart';
import 'package:eatvio_app/core/token_storage.dart';
@@ -41,6 +42,7 @@ class AuthScreen extends StatefulWidget {
class _AuthScreenState extends State<AuthScreen> {
bool checkboxState = false;
bool hidePassword = true;
final baseUrlController = TextEditingController();
@override
Widget build(BuildContext context) {
@@ -49,10 +51,54 @@ class _AuthScreenState extends State<AuthScreen> {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: SvgPicture.asset(
ImageConstant.imgLogoEatvio,
height: 48,
fit: BoxFit.contain,
title: GestureDetector(
onLongPress: () {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('Base url без https:// и /api'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
CustomTextFormField(
controller: baseUrlController,
hintText: 'dev2.eatvio.com',
),
const SizedBox(height: 12),
InkWell(
onTap: () async {
baseUrl = 'https://${baseUrlController.text}';
sl<Dio>().options.baseUrl = baseUrl;
},
borderRadius: BorderRadius.circular(20),
child: Ink(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: appTheme.blueA400,
),
child: Container(
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 12),
alignment: Alignment.center,
child: Text(
'Сохранить',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w600,
),
),
),
),
),
],
),
),
);
},
child: SvgPicture.asset(
ImageConstant.imgLogoEatvio,
height: 48,
fit: BoxFit.contain,
),
),
),
body: SafeArea(

View File

@@ -4,7 +4,6 @@ import 'package:eatvio_app/core/token_storage.dart';
import 'package:eatvio_app/core/utils/image_constant.dart';
import 'package:eatvio_app/core/locator_service.dart';
import 'package:eatvio_app/core/theme/theme_helper.dart';
import 'package:eatvio_app/core/widgets/custom_text_form_field.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:go_router/go_router.dart';
@@ -12,65 +11,12 @@ import 'package:go_router/go_router.dart';
class MenuScreen extends StatelessWidget {
MenuScreen({super.key});
final baseUrlController = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: false,
title: Text('Меню'),
actions: [
SizedBox(
width: MediaQuery.of(context).size.width * 0.7,
child: GestureDetector(
onLongPress: () {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('Base url без https:// и /api'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
CustomTextFormField(
controller: baseUrlController,
hintText: 'dev2.eatvio.com',
),
const SizedBox(height: 12),
InkWell(
onTap: () async {
await TokenStorage.removeTokenInStorage();
GoRouter.of(context).go('/auth-screen');
baseUrl = 'https://${baseUrlController.text}';
sl<Dio>().options.baseUrl = baseUrl;
},
borderRadius: BorderRadius.circular(20),
child: Ink(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: appTheme.blueA400,
),
child: Container(
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 12),
alignment: Alignment.center,
child: Text(
'Сохранить',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w600,
),
),
),
),
),
],
),
),
);
},
),
),
],
),
body: SingleChildScrollView(
child: Column(

View File

@@ -20,6 +20,7 @@ class UserRegistrationSheet with _$UserRegistrationSheet {
required String lang,
required int weight,
required int height,
required String phone,
@JsonKey(name: 'chest_circumference') required int chestCircumference,
@JsonKey(name: 'waist_circumference') required int waistCircumference,
@JsonKey(name: 'hip_circumference') required int hipCircumference,

View File

@@ -39,6 +39,7 @@ mixin _$UserRegistrationSheet {
String get lang => throw _privateConstructorUsedError;
int get weight => throw _privateConstructorUsedError;
int get height => throw _privateConstructorUsedError;
String get phone => throw _privateConstructorUsedError;
@JsonKey(name: 'chest_circumference')
int get chestCircumference => throw _privateConstructorUsedError;
@JsonKey(name: 'waist_circumference')
@@ -98,6 +99,7 @@ abstract class $UserRegistrationSheetCopyWith<$Res> {
String lang,
int weight,
int height,
String phone,
@JsonKey(name: 'chest_circumference') int chestCircumference,
@JsonKey(name: 'waist_circumference') int waistCircumference,
@JsonKey(name: 'hip_circumference') int hipCircumference,
@@ -143,6 +145,7 @@ class _$UserRegistrationSheetCopyWithImpl<$Res,
Object? lang = null,
Object? weight = null,
Object? height = null,
Object? phone = null,
Object? chestCircumference = null,
Object? waistCircumference = null,
Object? hipCircumference = null,
@@ -211,6 +214,10 @@ class _$UserRegistrationSheetCopyWithImpl<$Res,
? _value.height
: height // ignore: cast_nullable_to_non_nullable
as int,
phone: null == phone
? _value.phone
: phone // ignore: cast_nullable_to_non_nullable
as String,
chestCircumference: null == chestCircumference
? _value.chestCircumference
: chestCircumference // ignore: cast_nullable_to_non_nullable
@@ -294,6 +301,7 @@ abstract class _$$UserRegistrationSheetImplCopyWith<$Res>
String lang,
int weight,
int height,
String phone,
@JsonKey(name: 'chest_circumference') int chestCircumference,
@JsonKey(name: 'waist_circumference') int waistCircumference,
@JsonKey(name: 'hip_circumference') int hipCircumference,
@@ -337,6 +345,7 @@ class __$$UserRegistrationSheetImplCopyWithImpl<$Res>
Object? lang = null,
Object? weight = null,
Object? height = null,
Object? phone = null,
Object? chestCircumference = null,
Object? waistCircumference = null,
Object? hipCircumference = null,
@@ -405,6 +414,10 @@ class __$$UserRegistrationSheetImplCopyWithImpl<$Res>
? _value.height
: height // ignore: cast_nullable_to_non_nullable
as int,
phone: null == phone
? _value.phone
: phone // ignore: cast_nullable_to_non_nullable
as String,
chestCircumference: null == chestCircumference
? _value.chestCircumference
: chestCircumference // ignore: cast_nullable_to_non_nullable
@@ -483,6 +496,7 @@ class _$UserRegistrationSheetImpl implements _UserRegistrationSheet {
required this.lang,
required this.weight,
required this.height,
required this.phone,
@JsonKey(name: 'chest_circumference') required this.chestCircumference,
@JsonKey(name: 'waist_circumference') required this.waistCircumference,
@JsonKey(name: 'hip_circumference') required this.hipCircumference,
@@ -533,6 +547,8 @@ class _$UserRegistrationSheetImpl implements _UserRegistrationSheet {
@override
final int height;
@override
final String phone;
@override
@JsonKey(name: 'chest_circumference')
final int chestCircumference;
@override
@@ -577,7 +593,7 @@ class _$UserRegistrationSheetImpl implements _UserRegistrationSheet {
@override
String toString() {
return 'UserRegistrationSheet(firstName: $firstName, lastName: $lastName, email: $email, password: $password, passwordConfirmation: $passwordConfirmation, termsAccepted: $termsAccepted, birthdate: $birthdate, gender: $gender, location: $location, responseBody: $responseBody, lang: $lang, weight: $weight, height: $height, chestCircumference: $chestCircumference, waistCircumference: $waistCircumference, hipCircumference: $hipCircumference, bloodPressureUp: $bloodPressureUp, bloodPressureDown: $bloodPressureDown, hasHypo: $hasHypo, hasHyper: $hasHyper, aboutAllergy: $aboutAllergy, aboutTakingPils: $aboutTakingPils, aboutSportHobbies: $aboutSportHobbies, favoriteFoods: $favoriteFoods, unfavoriteFoods: $unfavoriteFoods, additionalInfo: $additionalInfo, activityCoefficient: $activityCoefficient)';
return 'UserRegistrationSheet(firstName: $firstName, lastName: $lastName, email: $email, password: $password, passwordConfirmation: $passwordConfirmation, termsAccepted: $termsAccepted, birthdate: $birthdate, gender: $gender, location: $location, responseBody: $responseBody, lang: $lang, weight: $weight, height: $height, phone: $phone, chestCircumference: $chestCircumference, waistCircumference: $waistCircumference, hipCircumference: $hipCircumference, bloodPressureUp: $bloodPressureUp, bloodPressureDown: $bloodPressureDown, hasHypo: $hasHypo, hasHyper: $hasHyper, aboutAllergy: $aboutAllergy, aboutTakingPils: $aboutTakingPils, aboutSportHobbies: $aboutSportHobbies, favoriteFoods: $favoriteFoods, unfavoriteFoods: $unfavoriteFoods, additionalInfo: $additionalInfo, activityCoefficient: $activityCoefficient)';
}
@override
@@ -606,6 +622,7 @@ class _$UserRegistrationSheetImpl implements _UserRegistrationSheet {
(identical(other.lang, lang) || other.lang == lang) &&
(identical(other.weight, weight) || other.weight == weight) &&
(identical(other.height, height) || other.height == height) &&
(identical(other.phone, phone) || other.phone == phone) &&
(identical(other.chestCircumference, chestCircumference) ||
other.chestCircumference == chestCircumference) &&
(identical(other.waistCircumference, waistCircumference) ||
@@ -652,6 +669,7 @@ class _$UserRegistrationSheetImpl implements _UserRegistrationSheet {
lang,
weight,
height,
phone,
chestCircumference,
waistCircumference,
hipCircumference,
@@ -701,6 +719,7 @@ abstract class _UserRegistrationSheet implements UserRegistrationSheet {
required final String lang,
required final int weight,
required final int height,
required final String phone,
@JsonKey(name: 'chest_circumference')
required final int chestCircumference,
@JsonKey(name: 'waist_circumference')
@@ -756,6 +775,8 @@ abstract class _UserRegistrationSheet implements UserRegistrationSheet {
@override
int get height;
@override
String get phone;
@override
@JsonKey(name: 'chest_circumference')
int get chestCircumference;
@override

View File

@@ -22,6 +22,7 @@ _$UserRegistrationSheetImpl _$$UserRegistrationSheetImplFromJson(
lang: json['lang'] as String,
weight: (json['weight'] as num).toInt(),
height: (json['height'] as num).toInt(),
phone: json['phone'] as String,
chestCircumference: (json['chest_circumference'] as num).toInt(),
waistCircumference: (json['waist_circumference'] as num).toInt(),
hipCircumference: (json['hip_circumference'] as num).toInt(),
@@ -55,6 +56,7 @@ Map<String, dynamic> _$$UserRegistrationSheetImplToJson(
'lang': instance.lang,
'weight': instance.weight,
'height': instance.height,
'phone': instance.phone,
'chest_circumference': instance.chestCircumference,
'waist_circumference': instance.waistCircumference,
'hip_circumference': instance.hipCircumference,

View File

@@ -40,6 +40,7 @@ class RegistrationCubit extends Cubit<RegistrationState> {
favoriteFoods: '',
unfavoriteFoods: '',
additionalInfo: '',
phone: '',
),
),
);
@@ -48,7 +49,11 @@ class RegistrationCubit extends Cubit<RegistrationState> {
Future<void> tryRegistration() async {
try {
final token = await registrationRepository.tryRegister(state.sheet);
final token = await registrationRepository.tryRegister(
state.sheet.copyWith(
phone: state.sheet.phone.replaceAll(' ', '').replaceAll('(', '').replaceAll(')', ''),
),
);
await TokenStorage.saveTokenInStorage(token);
AppRouter.navigatorKey.currentContext?.go('/my-profile-screen');
} catch (e) {

View File

@@ -0,0 +1,67 @@
import 'package:eatvio_app/core/widgets/custom_text_form_field.dart';
import 'package:eatvio_app/features/registration/models/user_registration_model.dart';
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:mask_text_input_formatter/mask_text_input_formatter.dart';
class PhoneScreen extends StatefulWidget {
final UserRegistrationSheet sheet;
const PhoneScreen({
super.key,
required this.sheet,
});
@override
State<PhoneScreen> createState() => _PhoneScreenState();
}
class _PhoneScreenState extends State<PhoneScreen> {
final phoneController = TextEditingController();
final phoneFocus = FocusNode();
final maskFormatter = MaskTextInputFormatter(
mask: '+7 (###) ### ## ##',
filter: {"#": RegExp(r'[0-9]')},
);
@override
void initState() {
super.initState();
if (widget.sheet.phone.isNotEmpty) phoneController.text = widget.sheet.phone;
phoneFocus.requestFocus();
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80, left: 16, right: 16, top: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Номер телефона'),
SizedBox(height: 4),
CustomTextFormField(
textInputAction: TextInputAction.done,
autofocus: true,
focusNode: phoneFocus,
hintText: '+7 (999) 999 99 99',
controller: phoneController,
keyboardType: TextInputType.number,
inputFormatters: [maskFormatter],
onChanged: (newValue) {
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit.updateSheet(
registrationCubit.state.sheet.copyWith(
phone: newValue,
),
);
},
),
],
),
);
}
}

View File

@@ -13,9 +13,9 @@ import 'package:eatvio_app/features/registration/presentation/pages/favorite_foo
import 'package:eatvio_app/features/registration/presentation/pages/favorite_sports_screen.dart';
import 'package:eatvio_app/features/registration/presentation/pages/gender_screen.dart';
import 'package:eatvio_app/features/registration/presentation/pages/height_screen.dart';
import 'package:eatvio_app/features/registration/presentation/pages/language_select_screen.dart';
import 'package:eatvio_app/features/registration/presentation/pages/medicine_intake_screen.dart';
import 'package:eatvio_app/features/registration/presentation/pages/name_screen.dart';
import 'package:eatvio_app/features/registration/presentation/pages/phone_screen.dart';
import 'package:eatvio_app/features/registration/presentation/pages/weight_screen.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:eatvio_app/core/locator_service.dart';
@@ -159,7 +159,8 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
});
},
children: [
LanguageSelectScreen(sheet: state.sheet),
// LanguageSelectScreen(sheet: state.sheet),
PhoneScreen(sheet: state.sheet),
CredentialsScreen(sheet: state.sheet),
NameScreen(sheet: state.sheet),
GenderScreen(sheet: state.sheet),