feature(registration): new registration flow

This commit is contained in:
mso7nueh
2024-07-11 14:49:50 +03:00
parent c3f7853d0e
commit aacba077b7
23 changed files with 2176 additions and 1967 deletions

View File

@@ -2,6 +2,7 @@ import 'package:eatvio_app/core/initialization_cubit/initialization_cubit.dart';
import 'package:eatvio_app/core/token_storage.dart';
import 'package:eatvio_app/features/chat/presentation/pages/chat_screen.dart';
import 'package:eatvio_app/features/chat/presentation/pages/chat_select_screen/chat_select_screen.dart';
import 'package:eatvio_app/features/registration/presentation/pages/registration_screen.dart';
import 'package:eatvio_app/presentation/auth/auth_screen/auth_screen.dart';
import 'package:eatvio_app/presentation/diary/diary_edit_screen/diary_edit_screen.dart';
import 'package:eatvio_app/presentation/diets/diet_create_screen/diet_create_screen.dart';
@@ -54,6 +55,11 @@ class AppRouter {
},
builder: (context, state) => AuthScreen.builder(context),
routes: [
GoRoute(
path: 'registration-screen',
name: 'registrationScreen',
builder: (context, state) => const RegistrationScreen(),
),
GoRoute(
path: 'language-select-screen',
name: 'languageSelectScreen',

View File

@@ -0,0 +1,10 @@
import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart';
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_state.dart';
import 'package:eatvio_app/presentation/registration/language_select_screen/models/language_select_model.dart';
class RegistrationCubit extends Cubit<RegistrationState> {
RegistrationCubit() : super(RegistrationState.loaded(sheet: LanguageSelectModel().userRegistrationSheet));
updateSheet(UserRegistrationSheet sheet) => emit(RegistrationState.loaded(sheet: sheet));
}

View File

@@ -0,0 +1,13 @@
import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'registration_state.freezed.dart';
@freezed
abstract class RegistrationState with _$RegistrationState {
const factory RegistrationState() = _RegistrationState;
const factory RegistrationState.loaded({
required UserRegistrationSheet sheet,
}) = RegistrationStateLoaded;
}

View File

@@ -0,0 +1,315 @@
// 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 'registration_state.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 _$RegistrationState {
@optionalTypeArgs
TResult when<TResult extends Object?>(
TResult Function() $default, {
required TResult Function(UserRegistrationSheet sheet) loaded,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>(
TResult? Function()? $default, {
TResult? Function(UserRegistrationSheet sheet)? loaded,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>(
TResult Function()? $default, {
TResult Function(UserRegistrationSheet sheet)? loaded,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>(
TResult Function(_RegistrationState value) $default, {
required TResult Function(RegistrationStateLoaded value) loaded,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>(
TResult? Function(_RegistrationState value)? $default, {
TResult? Function(RegistrationStateLoaded value)? loaded,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>(
TResult Function(_RegistrationState value)? $default, {
TResult Function(RegistrationStateLoaded value)? loaded,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $RegistrationStateCopyWith<$Res> {
factory $RegistrationStateCopyWith(
RegistrationState value, $Res Function(RegistrationState) then) =
_$RegistrationStateCopyWithImpl<$Res, RegistrationState>;
}
/// @nodoc
class _$RegistrationStateCopyWithImpl<$Res, $Val extends RegistrationState>
implements $RegistrationStateCopyWith<$Res> {
_$RegistrationStateCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
}
/// @nodoc
abstract class _$$RegistrationStateImplCopyWith<$Res> {
factory _$$RegistrationStateImplCopyWith(_$RegistrationStateImpl value,
$Res Function(_$RegistrationStateImpl) then) =
__$$RegistrationStateImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$RegistrationStateImplCopyWithImpl<$Res>
extends _$RegistrationStateCopyWithImpl<$Res, _$RegistrationStateImpl>
implements _$$RegistrationStateImplCopyWith<$Res> {
__$$RegistrationStateImplCopyWithImpl(_$RegistrationStateImpl _value,
$Res Function(_$RegistrationStateImpl) _then)
: super(_value, _then);
}
/// @nodoc
class _$RegistrationStateImpl implements _RegistrationState {
const _$RegistrationStateImpl();
@override
String toString() {
return 'RegistrationState()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$RegistrationStateImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>(
TResult Function() $default, {
required TResult Function(UserRegistrationSheet sheet) loaded,
}) {
return $default();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>(
TResult? Function()? $default, {
TResult? Function(UserRegistrationSheet sheet)? loaded,
}) {
return $default?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>(
TResult Function()? $default, {
TResult Function(UserRegistrationSheet sheet)? loaded,
required TResult orElse(),
}) {
if ($default != null) {
return $default();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>(
TResult Function(_RegistrationState value) $default, {
required TResult Function(RegistrationStateLoaded value) loaded,
}) {
return $default(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>(
TResult? Function(_RegistrationState value)? $default, {
TResult? Function(RegistrationStateLoaded value)? loaded,
}) {
return $default?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>(
TResult Function(_RegistrationState value)? $default, {
TResult Function(RegistrationStateLoaded value)? loaded,
required TResult orElse(),
}) {
if ($default != null) {
return $default(this);
}
return orElse();
}
}
abstract class _RegistrationState implements RegistrationState {
const factory _RegistrationState() = _$RegistrationStateImpl;
}
/// @nodoc
abstract class _$$RegistrationStateLoadedImplCopyWith<$Res> {
factory _$$RegistrationStateLoadedImplCopyWith(
_$RegistrationStateLoadedImpl value,
$Res Function(_$RegistrationStateLoadedImpl) then) =
__$$RegistrationStateLoadedImplCopyWithImpl<$Res>;
@useResult
$Res call({UserRegistrationSheet sheet});
}
/// @nodoc
class __$$RegistrationStateLoadedImplCopyWithImpl<$Res>
extends _$RegistrationStateCopyWithImpl<$Res, _$RegistrationStateLoadedImpl>
implements _$$RegistrationStateLoadedImplCopyWith<$Res> {
__$$RegistrationStateLoadedImplCopyWithImpl(
_$RegistrationStateLoadedImpl _value,
$Res Function(_$RegistrationStateLoadedImpl) _then)
: super(_value, _then);
@pragma('vm:prefer-inline')
@override
$Res call({
Object? sheet = null,
}) {
return _then(_$RegistrationStateLoadedImpl(
sheet: null == sheet
? _value.sheet
: sheet // ignore: cast_nullable_to_non_nullable
as UserRegistrationSheet,
));
}
}
/// @nodoc
class _$RegistrationStateLoadedImpl implements RegistrationStateLoaded {
const _$RegistrationStateLoadedImpl({required this.sheet});
@override
final UserRegistrationSheet sheet;
@override
String toString() {
return 'RegistrationState.loaded(sheet: $sheet)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$RegistrationStateLoadedImpl &&
(identical(other.sheet, sheet) || other.sheet == sheet));
}
@override
int get hashCode => Object.hash(runtimeType, sheet);
@JsonKey(ignore: true)
@override
@pragma('vm:prefer-inline')
_$$RegistrationStateLoadedImplCopyWith<_$RegistrationStateLoadedImpl>
get copyWith => __$$RegistrationStateLoadedImplCopyWithImpl<
_$RegistrationStateLoadedImpl>(this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>(
TResult Function() $default, {
required TResult Function(UserRegistrationSheet sheet) loaded,
}) {
return loaded(sheet);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>(
TResult? Function()? $default, {
TResult? Function(UserRegistrationSheet sheet)? loaded,
}) {
return loaded?.call(sheet);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>(
TResult Function()? $default, {
TResult Function(UserRegistrationSheet sheet)? loaded,
required TResult orElse(),
}) {
if (loaded != null) {
return loaded(sheet);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>(
TResult Function(_RegistrationState value) $default, {
required TResult Function(RegistrationStateLoaded value) loaded,
}) {
return loaded(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>(
TResult? Function(_RegistrationState value)? $default, {
TResult? Function(RegistrationStateLoaded value)? loaded,
}) {
return loaded?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>(
TResult Function(_RegistrationState value)? $default, {
TResult Function(RegistrationStateLoaded value)? loaded,
required TResult orElse(),
}) {
if (loaded != null) {
return loaded(this);
}
return orElse();
}
}
abstract class RegistrationStateLoaded implements RegistrationState {
const factory RegistrationStateLoaded(
{required final UserRegistrationSheet sheet}) =
_$RegistrationStateLoadedImpl;
UserRegistrationSheet get sheet;
@JsonKey(ignore: true)
_$$RegistrationStateLoadedImplCopyWith<_$RegistrationStateLoadedImpl>
get copyWith => throw _privateConstructorUsedError;
}

View File

@@ -0,0 +1,201 @@
import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/core/utils/image_constant.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/features/registration/presentation/bloc/registration_cubit/registration_state.dart';
import 'package:eatvio_app/presentation/registration/additional_information_screen/additional_information_screen.dart';
import 'package:eatvio_app/presentation/registration/allergies_screen/allergies_screen.dart';
import 'package:eatvio_app/presentation/registration/blood_pressure_screen/blood_pressure_screen.dart';
import 'package:eatvio_app/presentation/registration/body_circumferences_screen/body_circumferences_screen.dart';
import 'package:eatvio_app/presentation/registration/city_of_living_screen/city_of_living_screen.dart';
import 'package:eatvio_app/presentation/registration/credentials_screen/bloc/credentials_bloc.dart';
import 'package:eatvio_app/presentation/registration/credentials_screen/credentials_screen.dart';
import 'package:eatvio_app/presentation/registration/date_of_birth_screen/date_of_birth_screen.dart';
import 'package:eatvio_app/presentation/registration/favorite_foods_screen/favorite_foods_screen.dart';
import 'package:eatvio_app/presentation/registration/favorite_sports_screen/favorite_sports_screen.dart';
import 'package:eatvio_app/presentation/registration/gender_screen/gender_screen.dart';
import 'package:eatvio_app/presentation/registration/height_screen/height_screen.dart';
import 'package:eatvio_app/presentation/registration/language_select_screen/bloc/language_select_bloc.dart';
import 'package:eatvio_app/presentation/registration/language_select_screen/language_select_screen.dart';
import 'package:eatvio_app/presentation/registration/language_select_screen/models/language_select_model.dart';
import 'package:eatvio_app/presentation/registration/medicine_intake_screen/medicine_intake_screen.dart';
import 'package:eatvio_app/presentation/registration/name_screen/name_screen.dart';
import 'package:eatvio_app/presentation/registration/weight_screen/weight_screen.dart';
import 'package:eatvio_app/theme/theme_helper.dart';
import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
class RegistrationScreen extends StatefulWidget {
const RegistrationScreen({super.key});
@override
State<RegistrationScreen> createState() => _RegistrationScreenState();
}
class _RegistrationScreenState extends State<RegistrationScreen> {
double progressValue = 1 / 15;
int step = 1;
final pageController = PageController();
_showPopDialog() {
showDialog(
context: context,
builder: (context) => CupertinoAlertDialog(
content: Text('Отменить регистрацию? Заполненные данные не будут сохранены.'),
actions: [
CupertinoDialogAction(
onPressed: () {
Navigator.pop(context);
GoRouter.of(context).pop();
},
child: Text('Да'),
),
CupertinoDialogAction(
onPressed: () {
Navigator.pop(context);
},
isDefaultAction: true,
child: Text('Нет'),
)
],
),
);
}
@override
Widget build(BuildContext context) {
return BlocProvider<RegistrationCubit>(
create: (BuildContext context) => RegistrationCubit(),
child: BlocBuilder<RegistrationCubit, RegistrationState>(
builder: (BuildContext context, RegistrationState state) {
(state as RegistrationStateLoaded);
return PopScope(
canPop: false,
onPopInvoked: (_) => _showPopDialog(),
child: Scaffold(
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
floatingActionButton: Row(
children: [
Container(
height: 48,
width: MediaQuery.of(context).size.width * 0.2,
padding: EdgeInsets.only(left: 16, right: 4),
child: FloatingActionButton.extended(
heroTag: 'backButtonRegistration',
highlightElevation: 0,
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
backgroundColor: Color(0xFFEAF2FD),
onPressed: () {
if (pageController.page == 0) _showPopDialog();
setState(() {
pageController.previousPage(
duration: const Duration(milliseconds: 350),
curve: Curves.easeInOut,
);
});
},
label: Icon(
Icons.arrow_back_ios_new_rounded,
color: appTheme.blueA400,
),
),
),
Container(
height: 48,
width: MediaQuery.of(context).size.width * 0.8,
padding: EdgeInsets.only(left: 4, right: 16),
child: FloatingActionButton.extended(
heroTag: 'nextButtonRegistration',
highlightElevation: 0,
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
backgroundColor: appTheme.blueA400,
onPressed: () {
setState(() {
pageController.nextPage(
duration: const Duration(milliseconds: 350),
curve: Curves.easeInOut,
);
});
},
label: Text(
'Продолжить',
style: theme.textTheme.titleSmall,
),
),
),
],
),
appBar: AppBar(
automaticallyImplyLeading: true,
centerTitle: true,
title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio),
actions: [
Padding(
padding: const EdgeInsets.only(right: 16),
child: Text('шаг $step из 15'),
),
],
bottom: PreferredSize(
preferredSize: Size(MediaQuery.of(context).size.width, 32),
child: Padding(
padding: const EdgeInsets.all(16),
child: TweenAnimationBuilder<double>(
duration: const Duration(milliseconds: 350),
curve: Curves.easeInOut,
tween: Tween<double>(
begin: 0,
end: progressValue,
),
builder: (context, value, _) => LinearProgressIndicator(
value: value,
borderRadius: BorderRadius.circular(16),
minHeight: 8,
backgroundColor: Colors.grey.shade100,
valueColor: AlwaysStoppedAnimation<Color>(appTheme.blueA400),
),
),
),
),
),
body: PageView(
physics: NeverScrollableScrollPhysics(),
controller: pageController,
onPageChanged: (index) {
setState(() {
step = index + 1;
progressValue = step / 15;
});
},
children: [
LanguageSelectScreen.builder(context),
CredentialsScreen.builder(context, state.sheet),
NameScreen.builder(context, state.sheet),
GenderScreen.builder(context, state.sheet),
DateOfBirthScreen.builder(context, state.sheet),
CityOfLivingScreen.builder(context, state.sheet),
BodyCircumferencesScreen.builder(context, state.sheet),
WeightScreen.builder(context, state.sheet),
HeightScreen.builder(context, state.sheet),
BloodPressureScreen.builder(context, state.sheet),
AllergiesScreen.builder(context, state.sheet),
MedicineIntakeScreen.builder(context, state.sheet),
FavoriteSportsScreen.builder(context, state.sheet),
FavoriteFoodsScreen.builder(context, state.sheet),
AdditionalInformationScreen.builder(context, state.sheet),
],
),
),
);
},
),
);
}
}

View File

@@ -168,8 +168,11 @@ class AuthScreen extends StatelessWidget {
onTapNoAccount(BuildContext context) {
return () {
GoRouter.of(context).goNamed('languageSelectScreen');
GoRouter.of(context).goNamed('registrationScreen');
};
// return () {
// GoRouter.of(context).goNamed('languageSelectScreen');
// };
}
/// Section Widget

View File

@@ -29,46 +29,24 @@ class AdditionalInformationScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: _buildAppBar(context),
body: Container(
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80),
child: Container(
width: double.maxFinite,
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
child: Column(
children: [
SizedBox(height: 7.v),
Container(
height: 16.v,
width: 343.h,
decoration: BoxDecoration(
color: theme.colorScheme.onPrimary,
borderRadius: BorderRadius.circular(8.h),
border: Border.all(color: theme.colorScheme.primary, width: 1.h),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.h),
child: LinearProgressIndicator(
value: (14 / 15).toDouble(),
backgroundColor: theme.colorScheme.onPrimary,
valueColor: AlwaysStoppedAnimation<Color>(appTheme.blueA400),
),
),
),
SizedBox(height: 20.v),
SizedBox(height: 73.v),
_buildTextFormField(context),
Spacer(),
BlocBuilder<AdditionalInformationBloc, AdditionalInformationState>(
builder: (context, state) {
return NextStepButton(
text: "finish".tr.toUpperCase(),
margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v),
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
onPressed: onTapFinish(state, context),
);
},
),
// BlocBuilder<AdditionalInformationBloc, AdditionalInformationState>(
// builder: (context, state) {
// return NextStepButton(
// text: "finish".tr.toUpperCase(),
// margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v),
// buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
// onPressed: onTapFinish(state, context),
// );
// },
// ),
],
),
),

View File

@@ -28,57 +28,36 @@ class AllergiesScreen extends StatefulWidget {
class _AllergiesScreenState extends State<AllergiesScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: _buildAppBar(context),
body: Container(
width: double.maxFinite,
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
child: Column(
children: [
SizedBox(height: 7.v),
Container(
height: 16.v,
width: 343.h,
decoration: BoxDecoration(
color: theme.colorScheme.onPrimary,
borderRadius: BorderRadius.circular(8.h),
border: Border.all(color: theme.colorScheme.primary, width: 1.h),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.h),
child: LinearProgressIndicator(
value: (10 / 15).toDouble(),
backgroundColor: theme.colorScheme.onPrimary,
valueColor: AlwaysStoppedAnimation<Color>(appTheme.blueA400),
),
),
),
SizedBox(height: 22.v),
Text("allergies_presence".tr, style: theme.textTheme.headlineSmall),
Spacer(flex: 36),
_buildTextFormField(context),
Spacer(flex: 54),
BlocBuilder<AllergiesBloc, AllergiesState>(
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),
);
},
),
BlocBuilder<AllergiesBloc, AllergiesState>(
builder: (context, state) {
return GestureDetector(
onTap: onTapSkip(state, context),
child: Text("skip".tr, style: theme.textTheme.bodyLarge),
);
},
),
],
),
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80),
child: Container(
width: double.maxFinite,
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
child: Column(
children: [
Text("allergies_presence".tr, style: theme.textTheme.headlineSmall),
SizedBox(height: 22.v),
_buildTextFormField(context),
// BlocBuilder<AllergiesBloc, AllergiesState>(
// 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),
// );
// },
// ),
// BlocBuilder<AllergiesBloc, AllergiesState>(
// builder: (context, state) {
// return GestureDetector(
// onTap: onTapSkip(state, context),
// child: Text("skip".tr, style: theme.textTheme.bodyLarge),
// );
// },
// ),
],
),
),
);
}

View File

@@ -30,148 +30,123 @@ class BloodPressureScreen extends StatefulWidget {
}
class _BloodPressureScreenState extends State<BloodPressureScreen> {
final digitsOnly = FilteringTextInputFormatter.digitsOnly;
@override
Widget build(BuildContext context) {
final digitsOnly = FilteringTextInputFormatter.digitsOnly;
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: _buildAppBar(context),
body: Container(
width: double.maxFinite,
padding: EdgeInsets.symmetric(horizontal: 12.h, vertical: 9.v),
child: Column(
children: [
SizedBox(height: 7.v),
Container(
height: 16.v,
width: 343.h,
padding: EdgeInsets.symmetric(horizontal: 4.h),
// Apply padding directly to the Container
decoration: BoxDecoration(
color: theme.colorScheme.onPrimary,
borderRadius: BorderRadius.circular(8.h),
border: Border.all(
color: theme.colorScheme.primary,
width: 1.h,
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80),
child: Container(
width: double.maxFinite,
padding: EdgeInsets.symmetric(horizontal: 12.h, vertical: 9.v),
child: Column(
children: [
SizedBox(
width: 224.h,
child: Text(
"your_blood_pressure".tr,
maxLines: 2,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center,
style: theme.textTheme.headlineSmall,
),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.h),
child: LinearProgressIndicator(
value: (9 / 15).toDouble(),
backgroundColor: theme.colorScheme.onPrimary,
valueColor: AlwaysStoppedAnimation<Color>(appTheme.blueA400),
SizedBox(height: 21.v),
Container(
margin: EdgeInsets.only(right: 1.h),
padding: EdgeInsets.symmetric(horizontal: 3.h),
child: Column(
children: [
Text("up_pressure".tr, style: theme.textTheme.bodyLarge),
SizedBox(height: 2.v),
BlocSelector<BloodPressureBloc, BloodPressureState, TextEditingController?>(
selector: (state) => state.upPressureController,
builder: (context, upPressureController) {
return CustomTextFormField(inputFormatters: [digitsOnly], controller: upPressureController, hintText: "90".tr);
},
),
],
),
),
),
SizedBox(height: 21.v),
SizedBox(
width: 224.h,
child: Text(
"your_blood_pressure".tr,
maxLines: 2,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center,
style: theme.textTheme.headlineSmall,
),
),
SizedBox(height: 21.v),
Container(
margin: EdgeInsets.only(right: 1.h),
padding: EdgeInsets.symmetric(horizontal: 3.h),
child: Column(
children: [
Text("up_pressure".tr, style: theme.textTheme.bodyLarge),
SizedBox(height: 2.v),
BlocSelector<BloodPressureBloc, BloodPressureState, TextEditingController?>(
selector: (state) => state.upPressureController,
builder: (context, upPressureController) {
return CustomTextFormField(inputFormatters: [digitsOnly], controller: upPressureController, hintText: "90".tr);
},
),
],
),
),
SizedBox(height: 21.v),
Container(
margin: EdgeInsets.only(right: 1.h),
padding: EdgeInsets.symmetric(horizontal: 3.h),
child: Column(
children: [
Text("down_pressure".tr, style: theme.textTheme.bodyLarge),
SizedBox(height: 2.v),
BlocSelector<BloodPressureBloc, BloodPressureState, TextEditingController?>(
selector: (state) => state.downPressureController,
builder: (context, downPressureController) {
return CustomTextFormField(inputFormatters: [digitsOnly], controller: downPressureController, hintText: "90".tr);
},
),
],
),
),
SizedBox(height: 22.v),
Text("do_you_have_hypotension_tendency".tr, style: theme.textTheme.bodyLarge),
SizedBox(height: 2.v),
Padding(
padding: EdgeInsets.symmetric(horizontal: 4.h),
child: BlocSelector<BloodPressureBloc, BloodPressureState, BloodPressureModel?>(
selector: (state) => state.bloodPressureModelObj,
builder: (context, bloodPressureModelObj) {
return CustomDropDown(
icon: Container(
margin: EdgeInsets.fromLTRB(30.h, 11.v, 13.h, 11.v),
decoration: BoxDecoration(borderRadius: BorderRadius.circular(1.h)),
child: CustomImageView(imagePath: ImageConstant.imgFavorite, height: 12.adaptSize, width: 12.adaptSize),
SizedBox(height: 21.v),
Container(
margin: EdgeInsets.only(right: 1.h),
padding: EdgeInsets.symmetric(horizontal: 3.h),
child: Column(
children: [
Text("down_pressure".tr, style: theme.textTheme.bodyLarge),
SizedBox(height: 2.v),
BlocSelector<BloodPressureBloc, BloodPressureState, TextEditingController?>(
selector: (state) => state.downPressureController,
builder: (context, downPressureController) {
return CustomTextFormField(inputFormatters: [digitsOnly], controller: downPressureController, hintText: "90".tr);
},
),
hintText: "Не выбрано".tr,
items: bloodPressureModelObj?.dropdownItemList ?? [],
onChanged: onChangeHyper(context),
);
},
],
),
),
),
SizedBox(height: 22.v),
Text("do_you_have_hypertension_tendency".tr, style: theme.textTheme.bodyLarge),
SizedBox(height: 2.v),
Padding(
padding: EdgeInsets.symmetric(horizontal: 4.h),
child: BlocSelector<BloodPressureBloc, BloodPressureState, BloodPressureModel?>(
selector: (state) => state.bloodPressureModelObj,
builder: (context, bloodPressureModelObj) {
return CustomDropDown(
icon: Container(
margin: EdgeInsets.fromLTRB(30.h, 11.v, 13.h, 11.v),
decoration: BoxDecoration(borderRadius: BorderRadius.circular(1.h)),
child: CustomImageView(imagePath: ImageConstant.imgFavorite, height: 12.adaptSize, width: 12.adaptSize),
),
hintText: "Не выбрано".tr,
items: bloodPressureModelObj?.dropdownItemList ?? [],
onChanged: onChangeHypo(context),
);
},
SizedBox(height: 22.v),
Text("do_you_have_hypotension_tendency".tr, style: theme.textTheme.bodyLarge),
SizedBox(height: 2.v),
Padding(
padding: EdgeInsets.symmetric(horizontal: 4.h),
child: BlocSelector<BloodPressureBloc, BloodPressureState, BloodPressureModel?>(
selector: (state) => state.bloodPressureModelObj,
builder: (context, bloodPressureModelObj) {
return CustomDropDown(
icon: Container(
margin: EdgeInsets.fromLTRB(30.h, 11.v, 13.h, 11.v),
decoration: BoxDecoration(borderRadius: BorderRadius.circular(1.h)),
child: CustomImageView(imagePath: ImageConstant.imgFavorite, height: 12.adaptSize, width: 12.adaptSize),
),
hintText: "Не выбрано".tr,
items: bloodPressureModelObj?.dropdownItemList ?? [],
onChanged: onChangeHyper(context),
);
},
),
),
),
Spacer(),
BlocBuilder<BloodPressureBloc, BloodPressureState>(
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),
);
},
),
BlocBuilder<BloodPressureBloc, BloodPressureState>(
builder: (context, state) {
return GestureDetector(
onTap: onTapSkip(state, context),
child: Text("skip".tr, style: theme.textTheme.bodyLarge),
);
},
),
],
),
SizedBox(height: 22.v),
Text("do_you_have_hypertension_tendency".tr, style: theme.textTheme.bodyLarge),
SizedBox(height: 2.v),
Padding(
padding: EdgeInsets.symmetric(horizontal: 4.h),
child: BlocSelector<BloodPressureBloc, BloodPressureState, BloodPressureModel?>(
selector: (state) => state.bloodPressureModelObj,
builder: (context, bloodPressureModelObj) {
return CustomDropDown(
icon: Container(
margin: EdgeInsets.fromLTRB(30.h, 11.v, 13.h, 11.v),
decoration: BoxDecoration(borderRadius: BorderRadius.circular(1.h)),
child: CustomImageView(imagePath: ImageConstant.imgFavorite, height: 12.adaptSize, width: 12.adaptSize),
),
hintText: "Не выбрано".tr,
items: bloodPressureModelObj?.dropdownItemList ?? [],
onChanged: onChangeHypo(context),
);
},
),
),
// BlocBuilder<BloodPressureBloc, BloodPressureState>(
// 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),
// );
// },
// ),
// BlocBuilder<BloodPressureBloc, BloodPressureState>(
// builder: (context, state) {
// return GestureDetector(
// onTap: onTapSkip(state, context),
// child: Text("skip".tr, style: theme.textTheme.bodyLarge),
// );
// },
// ),
],
),
),
);
}

View File

@@ -12,7 +12,7 @@ import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_m
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
import 'package:flutter/material.dart';
class BodyCircumferencesScreen extends StatelessWidget {
class BodyCircumferencesScreen extends StatefulWidget {
const BodyCircumferencesScreen({Key? key}) : super(key: key);
static Widget builder(BuildContext context, sheet) {
@@ -23,87 +23,71 @@ class BodyCircumferencesScreen extends StatelessWidget {
);
}
@override
State<BodyCircumferencesScreen> createState() => _BodyCircumferencesScreenState();
}
class _BodyCircumferencesScreenState extends State<BodyCircumferencesScreen> {
final digitsOnly = FilteringTextInputFormatter.digitsOnly;
@override
Widget build(BuildContext context) {
final digitsOnly = FilteringTextInputFormatter.digitsOnly;
mediaQueryData = MediaQuery.of(context);
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: _buildAppBar(context),
body: Container(
width: double.maxFinite,
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
child: Column(
children: [
SizedBox(height: 7.v),
Container(
height: 16.v,
width: 343.h,
decoration: BoxDecoration(
color: theme.colorScheme.onPrimary,
borderRadius: BorderRadius.circular(8.h),
border: Border.all(color: theme.colorScheme.primary, width: 1.h),
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80),
child: Container(
width: double.maxFinite,
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
child: Column(
children: [
Text("initial_measurements".tr, style: theme.textTheme.headlineSmall),
SizedBox(height: 93.v),
Column(
children: [
Text("chest_circumference".tr, style: theme.textTheme.bodyLarge),
SizedBox(height: 3.v),
BlocSelector<BodyCircumferencesBloc, BodyCircumferencesState, TextEditingController?>(
selector: (state) => state.chestCircumferenceController,
builder: (context, chestCircumferenceController) {
return CustomTextFormField(inputFormatters: [digitsOnly], controller: chestCircumferenceController, hintText: "90".tr);
},
),
],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.h),
child: LinearProgressIndicator(
value: (6 / 15).toDouble(),
backgroundColor: theme.colorScheme.onPrimary,
valueColor: AlwaysStoppedAnimation<Color>(appTheme.blueA400),
),
SizedBox(height: 19.v),
Text("waist_circumference".tr, style: theme.textTheme.bodyLarge),
SizedBox(height: 5.v),
BlocSelector<BodyCircumferencesBloc, BodyCircumferencesState, TextEditingController?>(
selector: (state) => state.waistCircumferenceController,
builder: (context, waistCircumferenceController) {
return CustomTextFormField(inputFormatters: [digitsOnly], controller: waistCircumferenceController, hintText: "60".tr);
},
),
),
SizedBox(height: 39.v),
Text("initial_measurements".tr, style: theme.textTheme.headlineSmall),
SizedBox(height: 93.v),
Column(
children: [
Text("chest_circumference".tr, style: theme.textTheme.bodyLarge),
SizedBox(height: 3.v),
BlocSelector<BodyCircumferencesBloc, BodyCircumferencesState, TextEditingController?>(
selector: (state) => state.chestCircumferenceController,
builder: (context, chestCircumferenceController) {
return CustomTextFormField(inputFormatters: [digitsOnly], controller: chestCircumferenceController, hintText: "90".tr);
},
),
],
),
SizedBox(height: 19.v),
Text("waist_circumference".tr, style: theme.textTheme.bodyLarge),
SizedBox(height: 5.v),
BlocSelector<BodyCircumferencesBloc, BodyCircumferencesState, TextEditingController?>(
selector: (state) => state.waistCircumferenceController,
builder: (context, waistCircumferenceController) {
return CustomTextFormField(inputFormatters: [digitsOnly], controller: waistCircumferenceController, hintText: "60".tr);
},
),
SizedBox(height: 21.v),
Text("hip_circumference".tr, style: theme.textTheme.bodyLarge),
SizedBox(height: 3.v),
BlocSelector<BodyCircumferencesBloc, BodyCircumferencesState, TextEditingController?>(
selector: (state) => state.hipCircumferenceController,
builder: (context, hipCircumferenceController) {
return CustomTextFormField(
inputFormatters: [digitsOnly],
controller: hipCircumferenceController,
hintText: "90".tr,
textInputAction: TextInputAction.done,
);
},
),
Spacer(),
BlocBuilder<BodyCircumferencesBloc, BodyCircumferencesState>(
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),
);
},
),
],
),
SizedBox(height: 21.v),
Text("hip_circumference".tr, style: theme.textTheme.bodyLarge),
SizedBox(height: 3.v),
BlocSelector<BodyCircumferencesBloc, BodyCircumferencesState, TextEditingController?>(
selector: (state) => state.hipCircumferenceController,
builder: (context, hipCircumferenceController) {
return CustomTextFormField(
inputFormatters: [digitsOnly],
controller: hipCircumferenceController,
hintText: "90".tr,
textInputAction: TextInputAction.done,
);
},
),
// BlocBuilder<BodyCircumferencesBloc, BodyCircumferencesState>(
// 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),
// );
// },
// ),
],
),
),
);
}

View File

@@ -6,7 +6,6 @@ import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart';
import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart';
import 'package:validators/validators.dart';
import 'package:eatvio_app/widgets/next_step_button.dart';
import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart';
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
import 'package:flutter/material.dart';
@@ -25,34 +24,14 @@ class CredentialsScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
mediaQueryData = MediaQuery.of(context);
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: _buildAppBar(context),
body: Container(
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80),
child: Container(
width: double.maxFinite,
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(height: 7.v),
Container(
height: 16.v,
width: 343.h,
decoration: BoxDecoration(
color: theme.colorScheme.onPrimary,
borderRadius: BorderRadius.circular(8.h),
border: Border.all(color: theme.colorScheme.primary, width: 1.h),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.h),
child: LinearProgressIndicator(
value: (1 / 15).toDouble(),
backgroundColor: theme.colorScheme.onPrimary,
valueColor: AlwaysStoppedAnimation<Color>(appTheme.blueA400),
),
),
),
SizedBox(height: 39.v),
Text("user_registration".tr, style: theme.textTheme.headlineSmall),
SizedBox(height: 16.v),
Text("email".tr, style: theme.textTheme.bodyLarge),
@@ -93,17 +72,16 @@ class CredentialsScreen extends StatelessWidget {
return CustomTextFormField(obscureText: true, controller: passwordConfirmationController, textInputAction: TextInputAction.done);
},
),
Spacer(),
BlocBuilder<CredentialsBloc, CredentialsState>(
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),
);
},
),
// BlocBuilder<CredentialsBloc, CredentialsState>(
// 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),
// );
// },
// ),
],
),
),

View File

@@ -1,3 +1,4 @@
import 'package:flutter/cupertino.dart';
import 'package:go_router/go_router.dart';
import 'bloc/date_of_birth_bloc.dart';
@@ -35,53 +36,33 @@ class _DateOfBirthScreenState extends State<DateOfBirthScreen> {
@override
Widget build(BuildContext context) {
mediaQueryData = MediaQuery.of(context);
return BlocBuilder<DateOfBirthBloc, DateOfBirthState>(
builder: (context, state) {
return Scaffold(
appBar: _buildAppBar(context),
body: Container(
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: [
Container(
height: 16.v,
width: 343.h,
decoration: BoxDecoration(
color: theme.colorScheme.onPrimary,
borderRadius: BorderRadius.circular(8.h),
border: Border.all(color: theme.colorScheme.primary, width: 1.h),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.h),
child: LinearProgressIndicator(
value: (4 / 15).toDouble(),
backgroundColor: theme.colorScheme.onPrimary,
valueColor: AlwaysStoppedAnimation<Color>(appTheme.blueA400),
),
),
),
SizedBox(height: 38.v),
Text("date_of_birth".tr, style: theme.textTheme.headlineSmall),
Spacer(flex: 39),
const SizedBox(height: 32),
_buildDateInput(context),
Spacer(flex: 60),
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),
);
},
),
// 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),
// );
// },
// ),
],
),
),
);
},
);
},
),
);
}
@@ -138,10 +119,43 @@ class _DateOfBirthScreenState extends State<DateOfBirthScreen> {
onTapCalendar(BuildContext context) {
return () {
openDatePickerDialog(context);
// openDatePickerDialog(context);
_showDialog(
CupertinoDatePicker(
initialDateTime: DateTime.now(),
mode: CupertinoDatePickerMode.date,
onDateTimeChanged: (DateTime newTime) {
setState(() {
selectedDate = newTime;
});
},
),
);
};
}
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,
),
),
);
}
/// Navigates to the previous screen.
onTapArrowLeft(BuildContext context) {
GoRouter.of(context).pop();

View File

@@ -29,33 +29,13 @@ class FavoriteFoodsScreen extends StatefulWidget {
class _FavoriteFoodsScreenState extends State<FavoriteFoodsScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: _buildAppBar(context),
body: Container(
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80),
child: Container(
width: double.maxFinite,
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
child: Column(
children: [
SizedBox(height: 7.v),
Container(
height: 16.v,
width: 343.h,
decoration: BoxDecoration(
color: theme.colorScheme.onPrimary,
borderRadius: BorderRadius.circular(8.h),
border: Border.all(color: theme.colorScheme.primary, width: 1.h),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.h),
child: LinearProgressIndicator(
value: (13 / 15).toDouble(),
backgroundColor: theme.colorScheme.onPrimary,
valueColor: AlwaysStoppedAnimation<Color>(appTheme.blueA400),
),
),
),
SizedBox(height: 19.v),
Container(
width: 327.h,
margin: EdgeInsets.only(left: 8.h, right: 7.h),
@@ -71,25 +51,24 @@ class _FavoriteFoodsScreenState extends State<FavoriteFoodsScreen> {
_buildTextFormFieldFav(context),
SizedBox(height: 12.v),
_buildTextFormFieldUnfav(context),
Spacer(),
BlocBuilder<FavoriteFoodsBloc, FavoriteFoodsState>(
builder: (context, state) {
return NextStepButton(
text: "continue".tr.toUpperCase(),
margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 40.v),
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
onPressed: onTapContinue(state, context),
);
},
),
BlocBuilder<FavoriteFoodsBloc, FavoriteFoodsState>(
builder: (context, state) {
return GestureDetector(
onTap: onTapSkip(state, context),
child: Text("skip".tr, style: theme.textTheme.bodyLarge),
);
},
),
// BlocBuilder<FavoriteFoodsBloc, FavoriteFoodsState>(
// builder: (context, state) {
// return NextStepButton(
// text: "continue".tr.toUpperCase(),
// margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 40.v),
// buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
// onPressed: onTapContinue(state, context),
// );
// },
// ),
// BlocBuilder<FavoriteFoodsBloc, FavoriteFoodsState>(
// builder: (context, state) {
// return GestureDetector(
// onTap: onTapSkip(state, context),
// child: Text("skip".tr, style: theme.textTheme.bodyLarge),
// );
// },
// ),
],
),
),

View File

@@ -29,56 +29,35 @@ class FavoriteSportsScreen extends StatefulWidget {
class _FavoriteSportsScreenState extends State<FavoriteSportsScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: _buildAppBar(context),
body: Container(
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80),
child: Container(
width: double.maxFinite,
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 5.v),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(height: 20.v),
Container(
height: 16.v,
width: 343.h,
decoration: BoxDecoration(
color: theme.colorScheme.onPrimary,
borderRadius: BorderRadius.circular(8.h),
border: Border.all(color: theme.colorScheme.primary, width: 1.h),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.h),
child: LinearProgressIndicator(
value: (12 / 15).toDouble(),
backgroundColor: theme.colorScheme.onPrimary,
valueColor: AlwaysStoppedAnimation<Color>(appTheme.blueA400),
),
),
),
SizedBox(height: 38.v),
Text("your_favorite_sports".tr, style: theme.textTheme.headlineSmall),
Spacer(flex: 32),
SizedBox(height: 22.v),
_buildTextFormFieldSection(context),
Spacer(flex: 67),
BlocBuilder<FavoriteSportsBloc, FavoriteSportsState>(
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),
);
},
),
BlocBuilder<FavoriteSportsBloc, FavoriteSportsState>(
builder: (context, state) {
return GestureDetector(
onTap: onTapSkip(state, context),
child: Text("skip".tr, style: theme.textTheme.bodyLarge),
);
},
),
// BlocBuilder<FavoriteSportsBloc, FavoriteSportsState>(
// 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),
// );
// },
// ),
// BlocBuilder<FavoriteSportsBloc, FavoriteSportsState>(
// builder: (context, state) {
// return GestureDetector(
// onTap: onTapSkip(state, context),
// child: Text("skip".tr, style: theme.textTheme.bodyLarge),
// );
// },
// ),
],
),
),

View File

@@ -31,35 +31,15 @@ class GenderScreen extends StatefulWidget {
class _GenderScreenState extends State<GenderScreen> {
@override
Widget build(BuildContext context) {
mediaQueryData = MediaQuery.of(context);
return BlocBuilder<GenderBloc, GenderState>(
builder: (context, state) {
return Scaffold(
appBar: _buildAppBar(context),
body: Container(
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: [
SizedBox(height: 7.v),
Container(
height: 16.v,
width: 343.h,
decoration: BoxDecoration(
color: theme.colorScheme.onPrimary,
borderRadius: BorderRadius.circular(8.h),
border: Border.all(color: theme.colorScheme.primary, width: 1.h),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.h),
child: LinearProgressIndicator(
value: (3 / 15).toDouble(),
backgroundColor: theme.colorScheme.onPrimary,
valueColor: AlwaysStoppedAnimation<Color>(appTheme.blueA400),
),
),
),
SizedBox(height: 36.v),
Text("your_gender".tr, style: theme.textTheme.headlineSmall),
RadioListTile(
title: Text('Мужской'),
@@ -83,22 +63,21 @@ class _GenderScreenState extends State<GenderScreen> {
height: 40,
),
),
Spacer(flex: 66),
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),
);
},
),
// 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),
// );
// },
// ),
],
),
),
);
},
);
},
),
);
}

View File

@@ -24,84 +24,40 @@ class HeightScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
mediaQueryData = MediaQuery.of(context);
return Scaffold(
appBar: _buildAppBar(context),
body: Container(
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80),
child: Container(
width: double.maxFinite,
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
child: Column(
children: [
SizedBox(height: 7.v),
Container(
height: 16.v,
width: 343.h,
decoration: BoxDecoration(
color: theme.colorScheme.onPrimary,
borderRadius: BorderRadius.circular(8.h),
border: Border.all(
color: theme.colorScheme.primary,
width: 1.h,
),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.h),
child: LinearProgressIndicator(
value: (8 / 15).toDouble(),
backgroundColor: theme.colorScheme.onPrimary,
valueColor: AlwaysStoppedAnimation<Color>(
appTheme.blueA400,
),
),
),
Text(
"height_measurements".tr,
style: theme.textTheme.headlineSmall,
),
SizedBox(height: 39.v),
SizedBox(height: 174.v),
Column(
children: [
Text(
"height_measurements".tr,
style: theme.textTheme.headlineSmall,
"your_height".tr,
style: theme.textTheme.bodyLarge,
),
SizedBox(height: 174.v),
Column(
children: [
Text(
"your_height".tr,
style: theme.textTheme.bodyLarge,
),
SizedBox(height: 4.v),
BlocBuilder<HeightBloc, HeightState>(
builder: (context, state) {
return CustomTextFormField(
width: 150.h,
textInputAction: TextInputAction.done,
controller: state.heightController,
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly,
],
);
},
),
],
SizedBox(height: 4.v),
BlocBuilder<HeightBloc, HeightState>(
builder: (context, state) {
return CustomTextFormField(
width: 150.h,
textInputAction: TextInputAction.done,
controller: state.heightController,
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly,
],
);
},
),
],
),
Spacer(),
BlocBuilder<HeightBloc, HeightState>(
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),
);
},
),
],
),
),

View File

@@ -2,33 +2,29 @@ import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import '/core/app_export.dart';
import 'package:eatvio_app/presentation/registration/language_select_screen/models/language_select_model.dart';
part 'language_select_event.dart';
part 'language_select_state.dart';
/// A bloc that manages the state of a LanguageSelect according to the event that is dispatched to it.
class LanguageSelectBloc
extends Bloc<LanguageSelectEvent, LanguageSelectState> {
class LanguageSelectBloc extends Bloc<LanguageSelectEvent, LanguageSelectState> {
LanguageSelectBloc(LanguageSelectState initialState) : super(initialState) {
on<LanguageSelectInitialEvent>(_onInitialize);
on<ChangeDropDownEvent>(_changeDropDown);
}
_onInitialize(
LanguageSelectInitialEvent event,
Emitter<LanguageSelectState> emit,
) async {
emit(state.copyWith(
languageSelectModelObj: state.languageSelectModelObj
?.copyWith(dropdownItemList: fillDropdownItemList()),),);
_onInitialize(LanguageSelectInitialEvent event, Emitter<LanguageSelectState> emit) async {
emit(
state.copyWith(
languageSelectModelObj: state.languageSelectModelObj?.copyWith(dropdownItemList: fillDropdownItemList()),
),
);
}
_changeDropDown(
ChangeDropDownEvent event,
Emitter<LanguageSelectState> emit,
) {
_changeDropDown(ChangeDropDownEvent event, Emitter<LanguageSelectState> emit) {
emit(state.copyWith(selectedDropDownValue: event.value));
state.languageSelectModelObj?.userRegistrationSheet.lang =
event.value.title;
state.languageSelectModelObj?.userRegistrationSheet.lang = event.value.title;
}
List<SelectionPopupModel> fillDropdownItemList() {

View File

@@ -5,7 +5,6 @@ import 'bloc/language_select_bloc.dart';
import 'models/language_select_model.dart';
import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/widgets/custom_drop_down.dart';
import 'package:eatvio_app/widgets/next_step_button.dart';
import 'package:flutter/material.dart';
class LanguageSelectScreen extends StatelessWidget {
@@ -24,84 +23,57 @@ class LanguageSelectScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
width: double.maxFinite,
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 5.v),
child: Column(
children: [
CustomImageView(imagePath: ImageConstant.imgLogoEatvio, height: 50.adaptSize, width: 50.adaptSize),
SizedBox(height: 20.v),
Container(
height: 16.v,
width: 343.h,
decoration: BoxDecoration(
color: theme.colorScheme.onPrimary,
borderRadius: BorderRadius.circular(8.h),
border: Border.all(
color: theme.colorScheme.primary,
width: 1.h,
),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.h),
child: LinearProgressIndicator(
value: (0 / 15).toDouble(),
backgroundColor: theme.colorScheme.onPrimary,
valueColor: AlwaysStoppedAnimation<Color>(appTheme.blueA400),
),
),
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80),
child: Column(
children: [
Container(
width: 262.h,
margin: EdgeInsets.only(left: 41.h, right: 39.h),
child: Text(
"preferred_language".tr,
maxLines: 2,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center,
style: theme.textTheme.headlineSmall,
),
SizedBox(height: 20.v),
Container(
width: 262.h,
margin: EdgeInsets.only(left: 41.h, right: 39.h),
child: Text(
"preferred_language".tr,
maxLines: 2,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center,
style: theme.textTheme.headlineSmall,
),
),
Spacer(flex: 36),
BlocSelector<LanguageSelectBloc, LanguageSelectState, LanguageSelectModel?>(
selector: (state) => state.languageSelectModelObj,
builder: (
context,
languageSelectModelObj,
) {
return 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,
),
),
const SizedBox(height: 32),
BlocSelector<LanguageSelectBloc, LanguageSelectState, LanguageSelectModel?>(
selector: (state) => state.languageSelectModelObj,
builder: (
context,
languageSelectModelObj,
) {
return CustomDropDown(
icon: Container(
margin: EdgeInsets.fromLTRB(30.h, 11.v, 17.h, 11.v),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(1.h),
),
hintText: "Не выбрано".tr,
items: languageSelectModelObj?.dropdownItemList ?? [],
onChanged: (value) => _onDropDownChanged(context, value),
);
},
),
Spacer(flex: 63),
],
),
),
bottomNavigationBar: BlocBuilder<LanguageSelectBloc, LanguageSelectState>(
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: _saveAndPush(state, context),
);
},
child: CustomImageView(
imagePath: ImageConstant.imgFavorite,
height: 12.adaptSize,
width: 12.adaptSize,
),
),
hintText: "Не выбрано".tr,
items: languageSelectModelObj?.dropdownItemList ?? [],
onChanged: (value) => _onDropDownChanged(context, value),
);
},
),
// bottomNavigationBar: BlocBuilder<LanguageSelectBloc, LanguageSelectState>(
// 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: _saveAndPush(state, context),
// );
// },
// ),
],
),
);
}

View File

@@ -29,34 +29,13 @@ class MedicineIntakeScreen extends StatefulWidget {
class _MedicineIntakeScreenState extends State<MedicineIntakeScreen> {
@override
Widget build(BuildContext context) {
mediaQueryData = MediaQuery.of(context);
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: _buildAppBar(context),
body: Container(
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80),
child: Container(
width: double.maxFinite,
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
child: Column(
children: [
SizedBox(height: 7.v),
Container(
height: 16.v,
width: 343.h,
decoration: BoxDecoration(
color: theme.colorScheme.onPrimary,
borderRadius: BorderRadius.circular(8.h),
border: Border.all(color: theme.colorScheme.primary, width: 1.h),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.h),
child: LinearProgressIndicator(
value: (11 / 15).toDouble(),
backgroundColor: theme.colorScheme.onPrimary,
valueColor: AlwaysStoppedAnimation<Color>(appTheme.blueA400),
),
),
),
SizedBox(height: 20.v),
Container(
width: 271.h,
margin: EdgeInsets.only(left: 35.h, right: 36.h),
@@ -70,25 +49,24 @@ class _MedicineIntakeScreenState extends State<MedicineIntakeScreen> {
),
SizedBox(height: 86.v),
_buildTextFormField(context),
Spacer(),
BlocBuilder<MedicineIntakeBloc, MedicineIntakeState>(
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),
);
},
),
BlocBuilder<MedicineIntakeBloc, MedicineIntakeState>(
builder: (context, state) {
return GestureDetector(
onTap: onTapSkip(state, context),
child: Text("skip".tr, style: theme.textTheme.bodyLarge),
);
},
),
// BlocBuilder<MedicineIntakeBloc, MedicineIntakeState>(
// 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),
// );
// },
// ),
// BlocBuilder<MedicineIntakeBloc, MedicineIntakeState>(
// builder: (context, state) {
// return GestureDetector(
// onTap: onTapSkip(state, context),
// child: Text("skip".tr, style: theme.textTheme.bodyLarge),
// );
// },
// ),
],
),
),

View File

@@ -28,34 +28,13 @@ class NameScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
mediaQueryData = MediaQuery.of(context);
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: _buildAppBar(context),
body: Container(
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80),
child: Container(
width: double.maxFinite,
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
child: Column(
children: [
SizedBox(height: 7.v),
Container(
height: 16.v,
width: 343.h,
decoration: BoxDecoration(
color: theme.colorScheme.onPrimary,
borderRadius: BorderRadius.circular(8.h),
border: Border.all(color: theme.colorScheme.primary, width: 1.h),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.h),
child: LinearProgressIndicator(
value: (2 / 15).toDouble(),
backgroundColor: theme.colorScheme.onPrimary,
valueColor: AlwaysStoppedAnimation<Color>(appTheme.blueA400),
),
),
),
SizedBox(height: 39.v),
Text("what_is_your_name".tr, style: theme.textTheme.headlineSmall),
SizedBox(height: 93.v),
Text("first_name".tr, style: theme.textTheme.bodyLarge),
@@ -77,17 +56,16 @@ class NameScreen extends StatelessWidget {
);
},
),
Spacer(),
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
);
},
),
// 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
// );
// },
// ),
],
),
),

View File

@@ -24,85 +24,42 @@ class WeightScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: _buildAppBar(context),
body: Container(
width: double.maxFinite,
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
child: Column(
children: [
SizedBox(height: 7.v),
Container(
height: 16.v,
width: 343.h,
decoration: BoxDecoration(
color: theme.colorScheme.onPrimary,
borderRadius: BorderRadius.circular(8.h),
border: Border.all(
color: theme.colorScheme.primary,
width: 1.h,
),
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80),
child: Container(
width: double.maxFinite,
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
child: Column(
children: [
Text(
"weight_measurements".tr,
style: theme.textTheme.headlineSmall,
),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.h),
child: LinearProgressIndicator(
value: (7 / 15).toDouble(),
backgroundColor: theme.colorScheme.onPrimary,
valueColor: AlwaysStoppedAnimation<Color>(
appTheme.blueA400,
SizedBox(height: 174.v),
Column(
children: [
Text(
"your_weight".tr,
style: theme.textTheme.bodyLarge,
),
),
SizedBox(height: 4.v),
BlocBuilder<WeightBloc, WeightState>(
builder: (context, state) {
return CustomTextFormField(
width: 150.h,
textInputAction: TextInputAction.done,
controller: state.weightController,
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly,
],
);
},
),
],
),
),
SizedBox(height: 39.v),
Column(
children: [
Text(
"weight_measurements".tr,
style: theme.textTheme.headlineSmall,
),
SizedBox(height: 174.v),
Column(
children: [
Text(
"your_weight".tr,
style: theme.textTheme.bodyLarge,
),
SizedBox(height: 4.v),
BlocBuilder<WeightBloc, WeightState>(
builder: (context, state) {
return CustomTextFormField(
width: 150.h,
textInputAction: TextInputAction.done,
controller: state.weightController,
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly,
],
);
},
),
],
),
],
),
Spacer(),
BlocBuilder<WeightBloc, WeightState>(
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),
);
},
),
],
),
],
),
),
);
}

View File

@@ -26,14 +26,12 @@ class AppbarTitleImage extends StatelessWidget {
padding: margin ?? EdgeInsets.zero,
child: CustomImageView(
imagePath: imagePath,
height: 50.adaptSize,
width: 50.adaptSize,
height: 48,
fit: BoxFit.contain,
),
),
);
}
void onTapCall() {
}
void onTapCall() {}
}