forked from eatvio/eatvio_app
feature(registration): refactor i 2.
This commit is contained in:
@@ -1,15 +1,14 @@
|
||||
///SelectionPopupModel is common model
|
||||
///used for setting data into dropdowns
|
||||
class SelectionPopupModel {
|
||||
int? id;
|
||||
String title;
|
||||
dynamic value;
|
||||
bool isSelected;
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
SelectionPopupModel({
|
||||
this.id,
|
||||
required this.title,
|
||||
this.value,
|
||||
this.isSelected = false,
|
||||
});
|
||||
part 'selection_popup_model.freezed.dart';
|
||||
|
||||
@freezed
|
||||
class SelectionPopupModel with _$SelectionPopupModel {
|
||||
const factory SelectionPopupModel({
|
||||
int? id,
|
||||
required String title,
|
||||
dynamic value,
|
||||
@Default(false)
|
||||
bool isSelected,
|
||||
}) = _SelectionPopupModel;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
// coverage:ignore-file
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'selection_popup_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
T _$identity<T>(T value) => value;
|
||||
|
||||
final _privateConstructorUsedError = UnsupportedError(
|
||||
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
|
||||
|
||||
/// @nodoc
|
||||
mixin _$SelectionPopupModel {
|
||||
int? get id => throw _privateConstructorUsedError;
|
||||
String get title => throw _privateConstructorUsedError;
|
||||
dynamic get value => throw _privateConstructorUsedError;
|
||||
bool get isSelected => throw _privateConstructorUsedError;
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
$SelectionPopupModelCopyWith<SelectionPopupModel> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $SelectionPopupModelCopyWith<$Res> {
|
||||
factory $SelectionPopupModelCopyWith(
|
||||
SelectionPopupModel value, $Res Function(SelectionPopupModel) then) =
|
||||
_$SelectionPopupModelCopyWithImpl<$Res, SelectionPopupModel>;
|
||||
@useResult
|
||||
$Res call({int? id, String title, dynamic value, bool isSelected});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$SelectionPopupModelCopyWithImpl<$Res, $Val extends SelectionPopupModel>
|
||||
implements $SelectionPopupModelCopyWith<$Res> {
|
||||
_$SelectionPopupModelCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? id = freezed,
|
||||
Object? title = null,
|
||||
Object? value = freezed,
|
||||
Object? isSelected = null,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
id: freezed == id
|
||||
? _value.id
|
||||
: id // ignore: cast_nullable_to_non_nullable
|
||||
as int?,
|
||||
title: null == title
|
||||
? _value.title
|
||||
: title // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
value: freezed == value
|
||||
? _value.value
|
||||
: value // ignore: cast_nullable_to_non_nullable
|
||||
as dynamic,
|
||||
isSelected: null == isSelected
|
||||
? _value.isSelected
|
||||
: isSelected // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
) as $Val);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$SelectionPopupModelImplCopyWith<$Res>
|
||||
implements $SelectionPopupModelCopyWith<$Res> {
|
||||
factory _$$SelectionPopupModelImplCopyWith(_$SelectionPopupModelImpl value,
|
||||
$Res Function(_$SelectionPopupModelImpl) then) =
|
||||
__$$SelectionPopupModelImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call({int? id, String title, dynamic value, bool isSelected});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$SelectionPopupModelImplCopyWithImpl<$Res>
|
||||
extends _$SelectionPopupModelCopyWithImpl<$Res, _$SelectionPopupModelImpl>
|
||||
implements _$$SelectionPopupModelImplCopyWith<$Res> {
|
||||
__$$SelectionPopupModelImplCopyWithImpl(_$SelectionPopupModelImpl _value,
|
||||
$Res Function(_$SelectionPopupModelImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? id = freezed,
|
||||
Object? title = null,
|
||||
Object? value = freezed,
|
||||
Object? isSelected = null,
|
||||
}) {
|
||||
return _then(_$SelectionPopupModelImpl(
|
||||
id: freezed == id
|
||||
? _value.id
|
||||
: id // ignore: cast_nullable_to_non_nullable
|
||||
as int?,
|
||||
title: null == title
|
||||
? _value.title
|
||||
: title // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
value: freezed == value
|
||||
? _value.value
|
||||
: value // ignore: cast_nullable_to_non_nullable
|
||||
as dynamic,
|
||||
isSelected: null == isSelected
|
||||
? _value.isSelected
|
||||
: isSelected // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$SelectionPopupModelImpl implements _SelectionPopupModel {
|
||||
const _$SelectionPopupModelImpl(
|
||||
{this.id, required this.title, this.value, this.isSelected = false});
|
||||
|
||||
@override
|
||||
final int? id;
|
||||
@override
|
||||
final String title;
|
||||
@override
|
||||
final dynamic value;
|
||||
@override
|
||||
@JsonKey()
|
||||
final bool isSelected;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SelectionPopupModel(id: $id, title: $title, value: $value, isSelected: $isSelected)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$SelectionPopupModelImpl &&
|
||||
(identical(other.id, id) || other.id == id) &&
|
||||
(identical(other.title, title) || other.title == title) &&
|
||||
const DeepCollectionEquality().equals(other.value, value) &&
|
||||
(identical(other.isSelected, isSelected) ||
|
||||
other.isSelected == isSelected));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, id, title,
|
||||
const DeepCollectionEquality().hash(value), isSelected);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$SelectionPopupModelImplCopyWith<_$SelectionPopupModelImpl> get copyWith =>
|
||||
__$$SelectionPopupModelImplCopyWithImpl<_$SelectionPopupModelImpl>(
|
||||
this, _$identity);
|
||||
}
|
||||
|
||||
abstract class _SelectionPopupModel implements SelectionPopupModel {
|
||||
const factory _SelectionPopupModel(
|
||||
{final int? id,
|
||||
required final String title,
|
||||
final dynamic value,
|
||||
final bool isSelected}) = _$SelectionPopupModelImpl;
|
||||
|
||||
@override
|
||||
int? get id;
|
||||
@override
|
||||
String get title;
|
||||
@override
|
||||
dynamic get value;
|
||||
@override
|
||||
bool get isSelected;
|
||||
@override
|
||||
@JsonKey(ignore: true)
|
||||
_$$SelectionPopupModelImplCopyWith<_$SelectionPopupModelImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
@@ -171,11 +171,11 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
|
||||
});
|
||||
},
|
||||
children: [
|
||||
LanguageSelectScreen(sheet: context.read<RegistrationCubit>().state.sheet),
|
||||
CredentialsScreen(sheet: context.read<RegistrationCubit>().state.sheet),
|
||||
NameScreen(),
|
||||
GenderScreen(),
|
||||
DateOfBirthScreen(),
|
||||
LanguageSelectScreen(sheet: state.sheet),
|
||||
CredentialsScreen(sheet: state.sheet),
|
||||
NameScreen(sheet: state.sheet),
|
||||
GenderScreen(sheet: state.sheet),
|
||||
DateOfBirthScreen(sheet: state.sheet),
|
||||
CityOfLivingScreen(),
|
||||
BodyCircumferencesScreen(),
|
||||
WeightScreen(),
|
||||
@@ -197,38 +197,64 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
|
||||
|
||||
bool canGoNext(state) {
|
||||
switch (step) {
|
||||
case 2:
|
||||
List<String> errors = validateFields(state.sheet.email, state.sheet.name, state.sheet.password, state.sheet.passwordConfirmation);
|
||||
if (errors.isEmpty) {
|
||||
return true;
|
||||
} else {
|
||||
String errorMessage = '';
|
||||
|
||||
for (var error in errors) {
|
||||
errorMessage += error + '\n\n';
|
||||
}
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: Text('Ошибка'),
|
||||
content: Text(errorMessage),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
child: Text('OK'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
return false;
|
||||
}
|
||||
// case 2:
|
||||
// List<String> errors = validateCredentialsFields(state.sheet.email, state.sheet.name, state.sheet.password, state.sheet.passwordConfirmation);
|
||||
// if (errors.isEmpty) {
|
||||
// return true;
|
||||
// } else {
|
||||
// String errorMessage = '';
|
||||
//
|
||||
// for (var error in errors) {
|
||||
// errorMessage += error + '\n\n';
|
||||
// }
|
||||
//
|
||||
// showDialog(
|
||||
// context: context,
|
||||
// builder: (context) => AlertDialog(
|
||||
// title: Text('Ошибка'),
|
||||
// content: Text(errorMessage),
|
||||
// actions: [
|
||||
// TextButton(
|
||||
// onPressed: () => Navigator.pop(context),
|
||||
// child: Text('OK'),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// );
|
||||
// return false;
|
||||
// }
|
||||
// case 3:
|
||||
// List<String> errors = validateNameFields(state.sheet.firstName, state.sheet.lastName);
|
||||
// if (errors.isEmpty) {
|
||||
// return true;
|
||||
// } else {
|
||||
// String errorMessage = '';
|
||||
//
|
||||
// for (var error in errors) {
|
||||
// errorMessage += error + '\n\n';
|
||||
// }
|
||||
//
|
||||
// showDialog(
|
||||
// context: context,
|
||||
// builder: (context) => AlertDialog(
|
||||
// title: Text('Ошибка'),
|
||||
// content: Text(errorMessage),
|
||||
// actions: [
|
||||
// TextButton(
|
||||
// onPressed: () => Navigator.pop(context),
|
||||
// child: Text('OK'),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// );
|
||||
// return false;
|
||||
// }
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
List<String> validateFields(String email, String name, String password, String passwordConfirmation) {
|
||||
List<String> validateCredentialsFields(String email, String name, String password, String passwordConfirmation) {
|
||||
List<String> errors = [];
|
||||
|
||||
if (!isEmail(email)) {
|
||||
@@ -261,4 +287,26 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
List<String> validateNameFields(String firstName, String lastName) {
|
||||
List<String> errors = [];
|
||||
|
||||
if (firstName.isEmpty) {
|
||||
errors.add('First name cannot be empty');
|
||||
}
|
||||
|
||||
if (firstName.length < 1) {
|
||||
errors.add('First name is too short');
|
||||
}
|
||||
|
||||
if (lastName.isEmpty) {
|
||||
errors.add('Last name cannot be empty');
|
||||
}
|
||||
|
||||
if (lastName.length < 1) {
|
||||
errors.add('Last name is too short');
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,7 +175,7 @@ class GlossaryScreen extends StatelessWidget {
|
||||
),
|
||||
CustomDropDown(
|
||||
items: state.productGroups,
|
||||
defaultValue: state.productGroups?[0],
|
||||
value: state.productGroups?[0],
|
||||
fillColor: Colors.grey[200]!,
|
||||
hintText: 'Выберите категорию',
|
||||
borderDecoration: OutlineInputBorder(
|
||||
|
||||
@@ -1,82 +1,49 @@
|
||||
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'bloc/date_of_birth_bloc.dart';
|
||||
import 'models/date_of_birth_model.dart';
|
||||
import 'package:eatvio_app/core/app_export.dart';
|
||||
import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class DateOfBirthScreen extends StatefulWidget {
|
||||
const DateOfBirthScreen({Key? key}) : super(key: key);
|
||||
final UserRegistrationSheet sheet;
|
||||
|
||||
static Widget builder(BuildContext context, sheet) {
|
||||
return BlocProvider<DateOfBirthBloc>(
|
||||
create: (context) => DateOfBirthBloc(
|
||||
DateOfBirthState(
|
||||
dateOfBirthModelObj: DateOfBirthModel(
|
||||
userRegistrationSheet: sheet,
|
||||
),
|
||||
),
|
||||
)..add(DateOfBirthInitialEvent()),
|
||||
child: DateOfBirthScreen(),
|
||||
);
|
||||
}
|
||||
const DateOfBirthScreen({super.key, required this.sheet});
|
||||
|
||||
@override
|
||||
State<DateOfBirthScreen> createState() => _DateOfBirthScreenState();
|
||||
}
|
||||
|
||||
class _DateOfBirthScreenState extends State<DateOfBirthScreen> {
|
||||
DateTime selectedDate = DateTime.now();
|
||||
late DateTime selectedDate;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (widget.sheet.birthdate.isNotEmpty) {
|
||||
selectedDate = DateFormat('yyyy-mm-dd').parse(widget.sheet.birthdate);
|
||||
} else {
|
||||
selectedDate = DateTime.now();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SingleChildScrollView(
|
||||
padding: EdgeInsets.only(bottom: 80),
|
||||
child: BlocBuilder<DateOfBirthBloc, DateOfBirthState>(
|
||||
builder: (context, state) {
|
||||
return Container(
|
||||
width: double.maxFinite,
|
||||
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
|
||||
child: Column(
|
||||
children: [
|
||||
Text("date_of_birth".tr, style: theme.textTheme.headlineSmall),
|
||||
const SizedBox(height: 32),
|
||||
_buildDateInput(context),
|
||||
// BlocBuilder<DateOfBirthBloc, DateOfBirthState>(
|
||||
// builder: (context, state) {
|
||||
// return NextStepButton(
|
||||
// text: "continue".tr.toUpperCase(),
|
||||
// margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v),
|
||||
// buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
|
||||
// onPressed: onTapContinue(state, context),
|
||||
// );
|
||||
// },
|
||||
// ),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
width: double.maxFinite,
|
||||
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
|
||||
child: Column(
|
||||
children: [
|
||||
Text("date_of_birth".tr, style: theme.textTheme.headlineSmall),
|
||||
const SizedBox(height: 32),
|
||||
_buildDateInput(context),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
onTapContinue(DateOfBirthState state, BuildContext context) {
|
||||
return () {
|
||||
UserRegistrationSheet sheet = state.dateOfBirthModelObj!.userRegistrationSheet;
|
||||
// sheet.birthdate = selectedDate.toString();
|
||||
GoRouter.of(context).goNamed('cityOfLivingScreen', extra: sheet);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Function onTapBack(BuildContext context) {
|
||||
return () {
|
||||
onTapArrowLeft(context);
|
||||
};
|
||||
}
|
||||
|
||||
/// Section Widget
|
||||
_buildDateInput(BuildContext context) {
|
||||
return Container(
|
||||
@@ -105,14 +72,16 @@ class _DateOfBirthScreenState extends State<DateOfBirthScreen> {
|
||||
|
||||
onTapCalendar(BuildContext context) {
|
||||
return () {
|
||||
// openDatePickerDialog(context);
|
||||
_showDialog(
|
||||
CupertinoDatePicker(
|
||||
initialDateTime: DateTime.now(),
|
||||
mode: CupertinoDatePickerMode.date,
|
||||
onDateTimeChanged: (DateTime newTime) {
|
||||
onDateTimeChanged: (DateTime newDateTime) {
|
||||
setState(() {
|
||||
selectedDate = newTime;
|
||||
selectedDate = newDateTime;
|
||||
print(selectedDate);
|
||||
final registrationCubit = context.read<RegistrationCubit>();
|
||||
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(birthdate: selectedDate.toString()));
|
||||
});
|
||||
},
|
||||
),
|
||||
@@ -123,50 +92,26 @@ class _DateOfBirthScreenState extends State<DateOfBirthScreen> {
|
||||
void _showDialog(Widget child) {
|
||||
showCupertinoModalPopup<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) => Container(
|
||||
height: 216,
|
||||
padding: const EdgeInsets.only(top: 6.0),
|
||||
// The Bottom margin is provided to align the popup above the system
|
||||
// navigation bar.
|
||||
margin: EdgeInsets.only(
|
||||
bottom: MediaQuery.of(context).viewInsets.bottom,
|
||||
),
|
||||
// Provide a background color for the popup.
|
||||
color: CupertinoColors.systemBackground.resolveFrom(context),
|
||||
// Use a SafeArea widget to avoid system overlaps.
|
||||
child: SafeArea(
|
||||
top: false,
|
||||
child: child,
|
||||
),
|
||||
),
|
||||
builder: (BuildContext context) =>
|
||||
Container(
|
||||
height: 216,
|
||||
padding: const EdgeInsets.only(top: 6.0),
|
||||
// The Bottom margin is provided to align the popup above the system
|
||||
// navigation bar.
|
||||
margin: EdgeInsets.only(
|
||||
bottom: MediaQuery
|
||||
.of(context)
|
||||
.viewInsets
|
||||
.bottom,
|
||||
),
|
||||
// Provide a background color for the popup.
|
||||
color: CupertinoColors.systemBackground.resolveFrom(context),
|
||||
// Use a SafeArea widget to avoid system overlaps.
|
||||
child: SafeArea(
|
||||
top: false,
|
||||
child: child,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Navigates to the previous screen.
|
||||
onTapArrowLeft(BuildContext context) {
|
||||
GoRouter.of(context).pop();
|
||||
}
|
||||
|
||||
/// Displays a date picker dialog to update the selected date
|
||||
///
|
||||
/// This function returns a `Future` that completes with `void`.
|
||||
Future<void> openDatePickerDialog(BuildContext context) async {
|
||||
DateTime? dateTime = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: DateTime.now(),
|
||||
firstDate: DateTime(1924),
|
||||
lastDate: DateTime(
|
||||
DateTime.now().year,
|
||||
DateTime.now().month,
|
||||
DateTime.now().day,
|
||||
),
|
||||
);
|
||||
if (dateTime != null) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
selectedDate = dateTime;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,111 +1,79 @@
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'bloc/gender_bloc.dart';
|
||||
import 'models/gender_model.dart';
|
||||
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart';
|
||||
import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart';
|
||||
import 'package:eatvio_app/core/app_export.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class GenderScreen extends StatefulWidget {
|
||||
const GenderScreen({Key? key}) : super(key: key);
|
||||
final UserRegistrationSheet sheet;
|
||||
|
||||
static Widget builder(BuildContext context, sheet) {
|
||||
return BlocProvider<GenderBloc>(
|
||||
create: (context) => GenderBloc(
|
||||
GenderState(
|
||||
genderModelObj: GenderModel(userRegistrationSheet: sheet),
|
||||
),
|
||||
)..add(GenderInitialEvent()),
|
||||
child: GenderScreen(),
|
||||
);
|
||||
}
|
||||
const GenderScreen({super.key, required this.sheet});
|
||||
|
||||
@override
|
||||
State<GenderScreen> createState() => _GenderScreenState();
|
||||
}
|
||||
|
||||
class _GenderScreenState extends State<GenderScreen> {
|
||||
late String currentValue;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
currentValue = widget.sheet.gender;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SingleChildScrollView(
|
||||
padding: EdgeInsets.only(bottom: 80),
|
||||
child: BlocBuilder<GenderBloc, GenderState>(
|
||||
builder: (context, state) {
|
||||
return Container(
|
||||
width: double.maxFinite,
|
||||
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
|
||||
child: Column(
|
||||
children: [
|
||||
Text("your_gender".tr, style: theme.textTheme.headlineSmall),
|
||||
RadioListTile(
|
||||
title: Text('Мужской'),
|
||||
value: 'male',
|
||||
groupValue: state.selectedRadioValue,
|
||||
onChanged: onMale(context),
|
||||
secondary: Image.asset(
|
||||
'assets/images/img_male.png',
|
||||
width: 40,
|
||||
height: 40,
|
||||
),
|
||||
),
|
||||
RadioListTile(
|
||||
title: Text('Женский'),
|
||||
value: 'female',
|
||||
groupValue: state.selectedRadioValue,
|
||||
onChanged: onFemale(context),
|
||||
secondary: Image.asset(
|
||||
'assets/images/img_female.png',
|
||||
width: 40,
|
||||
height: 40,
|
||||
),
|
||||
),
|
||||
// BlocBuilder<GenderBloc, GenderState>(
|
||||
// builder: (context, state) {
|
||||
// return NextStepButton(
|
||||
// text: "continue".tr.toUpperCase(),
|
||||
// margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v),
|
||||
// buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
|
||||
// onPressed: onTapNext(state, context),
|
||||
// );
|
||||
// },
|
||||
// ),
|
||||
],
|
||||
child: Container(
|
||||
width: double.maxFinite,
|
||||
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
|
||||
child: Column(
|
||||
children: [
|
||||
Text("your_gender".tr, style: theme.textTheme.headlineSmall),
|
||||
RadioListTile(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
title: Text('Мужской'),
|
||||
value: 'male',
|
||||
groupValue: currentValue,
|
||||
onChanged: (newValue) {
|
||||
final registrationCubit = context.read<RegistrationCubit>();
|
||||
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(gender: 'male'));
|
||||
setState(() {
|
||||
currentValue = 'male';
|
||||
});
|
||||
},
|
||||
secondary: Image.asset(
|
||||
'assets/images/img_male.png',
|
||||
width: 40,
|
||||
height: 40,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
RadioListTile(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
title: Text('Женский'),
|
||||
value: 'female',
|
||||
groupValue: currentValue,
|
||||
onChanged: (newValue) {
|
||||
final registrationCubit = context.read<RegistrationCubit>();
|
||||
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(gender: 'female'));
|
||||
setState(() {
|
||||
currentValue = 'female';
|
||||
});
|
||||
},
|
||||
secondary: Image.asset(
|
||||
'assets/images/img_female.png',
|
||||
width: 40,
|
||||
height: 40,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
onTapNext(GenderState state, BuildContext context) {
|
||||
return () {
|
||||
UserRegistrationSheet sheet = state.genderModelObj!.userRegistrationSheet;
|
||||
// sheet.gender = state.selectedRadioValue!;
|
||||
GoRouter.of(context).goNamed('dateOfBirthScreen', extra: sheet);
|
||||
};
|
||||
}
|
||||
|
||||
onMale(BuildContext context) {
|
||||
return (value) {
|
||||
BlocProvider.of<GenderBloc>(context).add(GenderSelectEvent(value: 'male'));
|
||||
};
|
||||
}
|
||||
|
||||
onFemale(BuildContext context) {
|
||||
return (value) {
|
||||
BlocProvider.of<GenderBloc>(context).add(GenderSelectEvent(value: 'female'));
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Function onTapBack() {
|
||||
return () {
|
||||
GoRouter.of(context).pop();
|
||||
};
|
||||
}
|
||||
|
||||
/// Navigates to the previous screen.
|
||||
onTapArrowLeft(BuildContext context) {
|
||||
GoRouter.of(context).pop();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,12 +18,14 @@ class _LanguageSelectScreenState extends State<LanguageSelectScreen> {
|
||||
SelectionPopupModel(id: 1, title: "Русский", isSelected: true),
|
||||
];
|
||||
|
||||
late SelectionPopupModel value;
|
||||
SelectionPopupModel? value;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
value = SelectionPopupModel(title: widget.sheet.lang);
|
||||
if (widget.sheet.lang.isNotEmpty) {
|
||||
value = dropdownItemList.first;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -45,23 +47,13 @@ class _LanguageSelectScreenState extends State<LanguageSelectScreen> {
|
||||
),
|
||||
const SizedBox(height: 32),
|
||||
CustomDropDown(
|
||||
icon: Container(
|
||||
margin: EdgeInsets.fromLTRB(30.h, 11.v, 17.h, 11.v),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(1.h),
|
||||
),
|
||||
child: CustomImageView(
|
||||
imagePath: ImageConstant.imgFavorite,
|
||||
height: 12.adaptSize,
|
||||
width: 12.adaptSize,
|
||||
),
|
||||
),
|
||||
value: value,
|
||||
hintText: "Не выбрано".tr,
|
||||
items: dropdownItemList,
|
||||
onChanged: (SelectionPopupModel newValue) => setState(() {
|
||||
value = newValue;
|
||||
final registrationCubit = context.read<RegistrationCubit>();
|
||||
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(lang: value.title));
|
||||
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(lang: value!.title));
|
||||
}),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -1,22 +1,27 @@
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'bloc/name_bloc.dart';
|
||||
import 'models/name_model.dart';
|
||||
import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart';
|
||||
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart';
|
||||
import 'package:eatvio_app/core/app_export.dart';
|
||||
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class NameScreen extends StatelessWidget {
|
||||
const NameScreen({Key? key}) : super(key: key);
|
||||
class NameScreen extends StatefulWidget {
|
||||
final UserRegistrationSheet sheet;
|
||||
|
||||
static Widget builder(BuildContext context, sheet) {
|
||||
return BlocProvider<NameBloc>(
|
||||
create: (context) => NameBloc(
|
||||
NameState(
|
||||
nameModelObj: NameModel(userRegistrationSheet: sheet),
|
||||
),
|
||||
)..add(NameInitialEvent()),
|
||||
child: NameScreen(),
|
||||
);
|
||||
const NameScreen({required this.sheet, super.key});
|
||||
|
||||
@override
|
||||
State<NameScreen> createState() => _NameScreenState();
|
||||
}
|
||||
|
||||
class _NameScreenState extends State<NameScreen> {
|
||||
final firstNameController = TextEditingController();
|
||||
final lastNameController = TextEditingController();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
firstNameController.text = widget.sheet.firstName;
|
||||
lastNameController.text = widget.sheet.lastName;
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -32,101 +37,27 @@ class NameScreen extends StatelessWidget {
|
||||
SizedBox(height: 16.v),
|
||||
Text("first_name".tr, style: theme.textTheme.bodyLarge),
|
||||
SizedBox(height: 3.v),
|
||||
BlocSelector<NameBloc, NameState, TextEditingController?>(
|
||||
selector: (state) => state.firstNameController,
|
||||
builder: (context, firstNameController) {
|
||||
return CustomTextFormField(controller: firstNameController, textInputAction: TextInputAction.done);
|
||||
CustomTextFormField(
|
||||
controller: firstNameController,
|
||||
textInputAction: TextInputAction.done,
|
||||
onChanged: (newValue) {
|
||||
final registrationCubit = context.read<RegistrationCubit>();
|
||||
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(firstName: newValue));
|
||||
},
|
||||
),
|
||||
SizedBox(height: 19.v),
|
||||
Text("last_name".tr, style: theme.textTheme.bodyLarge),
|
||||
SizedBox(height: 5.v),
|
||||
BlocSelector<NameBloc, NameState, TextEditingController?>(
|
||||
selector: (state) => state.lastNameController,
|
||||
builder: (context, lastNameController) {
|
||||
return CustomTextFormField(
|
||||
controller: lastNameController,
|
||||
);
|
||||
CustomTextFormField(
|
||||
controller: lastNameController,
|
||||
onChanged: (newValue) {
|
||||
final registrationCubit = context.read<RegistrationCubit>();
|
||||
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(lastName: newValue));
|
||||
},
|
||||
),
|
||||
// BlocBuilder<NameBloc, NameState>(
|
||||
// builder: (context, state) {
|
||||
// return NextStepButton(
|
||||
// text: "continue".tr.toUpperCase(),
|
||||
// margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v),
|
||||
// buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
|
||||
// onPressed: () => _onTapNext(context, state), // Assign callback function here
|
||||
// );
|
||||
// },
|
||||
// ),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/// Navigates to the previous screen.
|
||||
onTapArrowLeft(BuildContext context) {
|
||||
GoRouter.of(context).pop();
|
||||
}
|
||||
|
||||
// _onTapNext(BuildContext context, NameState state) {
|
||||
// if (state.firstNameController != null && state.lastNameController != null) {
|
||||
// List<String> errors = validateFields(state.firstNameController!.text, state.lastNameController!.text);
|
||||
//
|
||||
// if (errors.isEmpty) {
|
||||
// UserRegistrationSheet sheet = state.nameModelObj!.userRegistrationSheet;
|
||||
// sheet.firstName = state.firstNameController!.text;
|
||||
// sheet.lastName = state.lastNameController!.text;
|
||||
// AppRouter.navigatorKey.currentContext?.goNamed('genderScreen', extra: sheet);
|
||||
// } else {
|
||||
// String errorMessage = '';
|
||||
//
|
||||
// for (var error in errors) {
|
||||
// errorMessage += error + '\n\n';
|
||||
// }
|
||||
//
|
||||
// showDialog(
|
||||
// context: context,
|
||||
// builder: (context) => AlertDialog(
|
||||
// title: Text('Error'),
|
||||
// content: Text(errorMessage),
|
||||
// actions: [
|
||||
// TextButton(
|
||||
// onPressed: () => onTapOk(context),
|
||||
// child: Text('OK'),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
void onTapOk(BuildContext context) {
|
||||
Navigator.pop(context);
|
||||
}
|
||||
|
||||
List<String> validateFields(String firstName, String lastName) {
|
||||
List<String> errors = [];
|
||||
|
||||
if (firstName.isEmpty) {
|
||||
errors.add('First name cannot be empty');
|
||||
}
|
||||
|
||||
if (firstName.length < 1) {
|
||||
errors.add('First name is too short');
|
||||
}
|
||||
|
||||
if (lastName.isEmpty) {
|
||||
errors.add('Last name cannot be empty');
|
||||
}
|
||||
|
||||
if (lastName.length < 1) {
|
||||
errors.add('Last name is too short');
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ class CustomDropDown extends StatelessWidget {
|
||||
this.filled = true,
|
||||
this.validator,
|
||||
this.onChanged,
|
||||
this.defaultValue,
|
||||
this.value,
|
||||
}) : super(
|
||||
key: key,
|
||||
);
|
||||
@@ -62,7 +62,7 @@ class CustomDropDown extends StatelessWidget {
|
||||
|
||||
final bool? filled;
|
||||
|
||||
final SelectionPopupModel? defaultValue;
|
||||
final SelectionPopupModel? value;
|
||||
|
||||
final FormFieldValidator<SelectionPopupModel>? validator;
|
||||
|
||||
@@ -85,6 +85,7 @@ class CustomDropDown extends StatelessWidget {
|
||||
focusNode: focusNode ?? FocusNode(),
|
||||
icon: icon,
|
||||
autofocus: autofocus!,
|
||||
value: value,
|
||||
isExpanded: true,
|
||||
style: textStyle ?? Theme.of(context).textTheme.titleMedium,
|
||||
items: items?.map((SelectionPopupModel item) {
|
||||
|
||||
Reference in New Issue
Block a user