feat: add settings

This commit is contained in:
mso7nueh
2024-09-27 11:55:42 +03:00
parent 2dcb677c7c
commit 346404503e
19 changed files with 1143 additions and 668 deletions

View File

@@ -12,9 +12,9 @@ import 'package:eatvio_app/locator_service.dart';
import 'package:eatvio_app/theme/app_decoration.dart';
import 'package:eatvio_app/theme/custom_text_style.dart';
import 'package:eatvio_app/theme/theme_helper.dart';
import 'package:eatvio_app/widgets/custom_edit_drop_down.dart';
import 'package:eatvio_app/widgets/custom_edit_text_form_field.dart';
import 'package:eatvio_app/widgets/custom_drop_down.dart';
import 'package:eatvio_app/widgets/custom_scale_element.dart';
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -430,7 +430,7 @@ class DiaryScreen extends StatelessWidget {
horizontal: 12,
vertical: 12,
),
defaultValue: state.mealList[0],
// defaultValue: state.mealList[0],
onChanged: changeMeal(context, state),
);
},
@@ -525,7 +525,7 @@ class DiaryScreen extends StatelessWidget {
builder: (context, diary) {
return CustomDropDown(
items: state.portionList,
defaultValue: state.portionController,
// defaultValue: state.portionController,
onChanged: changePortion(context, state),
);
},

View File

@@ -2,7 +2,7 @@ import 'package:eatvio_app/data/models/selectionPopupModel/selection_popup_model
import 'package:eatvio_app/features/registration/models/user_registration_model.dart';
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart';
import 'package:eatvio_app/theme/theme_helper.dart';
import 'package:eatvio_app/widgets/custom_edit_text_form_field.dart';
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

View File

@@ -72,7 +72,6 @@ class _DateOfBirthScreenState extends State<DateOfBirthScreen> {
onDateTimeChanged: (DateTime newDateTime) {
setState(() {
selectedDate = newDateTime;
print(selectedDate);
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(birthdate: selectedDate.toString()));
});

View File

@@ -58,7 +58,7 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
focusElevation: 0,
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
borderRadius: BorderRadius.circular(20),
),
backgroundColor: Color(0xFFEAF2FD),
onPressed: () async {
@@ -85,7 +85,7 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
elevation: 0,
focusElevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
borderRadius: BorderRadius.circular(20),
),
backgroundColor: appTheme.blueA400,
onPressed: () async {

View File

@@ -0,0 +1,6 @@
import 'package:eatvio_app/features/settings/presentation/bloc/settings_cubit/settings_state.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class SettingsCubit extends Cubit {
SettingsCubit() : super(SettingsState());
}

View File

@@ -0,0 +1,13 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'settings_state.freezed.dart';
@freezed
abstract class SettingsState with _$SettingsState {
const factory SettingsState() = _SettingsState;
const factory SettingsState.loading() = SettingsStateLoading;
const factory SettingsState.loaded() = SettingsStateLoaded;
const factory SettingsState.error({
required String errorMessage,
}) = SettingsStateError;
}

View File

@@ -0,0 +1,598 @@
// 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 'settings_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 _$SettingsState {
@optionalTypeArgs
TResult when<TResult extends Object?>(
TResult Function() $default, {
required TResult Function() loading,
required TResult Function() loaded,
required TResult Function(String errorMessage) error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>(
TResult? Function()? $default, {
TResult? Function()? loading,
TResult? Function()? loaded,
TResult? Function(String errorMessage)? error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>(
TResult Function()? $default, {
TResult Function()? loading,
TResult Function()? loaded,
TResult Function(String errorMessage)? error,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>(
TResult Function(_SettingsState value) $default, {
required TResult Function(SettingsStateLoading value) loading,
required TResult Function(SettingsStateLoaded value) loaded,
required TResult Function(SettingsStateError value) error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>(
TResult? Function(_SettingsState value)? $default, {
TResult? Function(SettingsStateLoading value)? loading,
TResult? Function(SettingsStateLoaded value)? loaded,
TResult? Function(SettingsStateError value)? error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>(
TResult Function(_SettingsState value)? $default, {
TResult Function(SettingsStateLoading value)? loading,
TResult Function(SettingsStateLoaded value)? loaded,
TResult Function(SettingsStateError value)? error,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $SettingsStateCopyWith<$Res> {
factory $SettingsStateCopyWith(
SettingsState value, $Res Function(SettingsState) then) =
_$SettingsStateCopyWithImpl<$Res, SettingsState>;
}
/// @nodoc
class _$SettingsStateCopyWithImpl<$Res, $Val extends SettingsState>
implements $SettingsStateCopyWith<$Res> {
_$SettingsStateCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of SettingsState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
abstract class _$$SettingsStateImplCopyWith<$Res> {
factory _$$SettingsStateImplCopyWith(
_$SettingsStateImpl value, $Res Function(_$SettingsStateImpl) then) =
__$$SettingsStateImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$SettingsStateImplCopyWithImpl<$Res>
extends _$SettingsStateCopyWithImpl<$Res, _$SettingsStateImpl>
implements _$$SettingsStateImplCopyWith<$Res> {
__$$SettingsStateImplCopyWithImpl(
_$SettingsStateImpl _value, $Res Function(_$SettingsStateImpl) _then)
: super(_value, _then);
/// Create a copy of SettingsState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$SettingsStateImpl implements _SettingsState {
const _$SettingsStateImpl();
@override
String toString() {
return 'SettingsState()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$SettingsStateImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>(
TResult Function() $default, {
required TResult Function() loading,
required TResult Function() loaded,
required TResult Function(String errorMessage) error,
}) {
return $default();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>(
TResult? Function()? $default, {
TResult? Function()? loading,
TResult? Function()? loaded,
TResult? Function(String errorMessage)? error,
}) {
return $default?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>(
TResult Function()? $default, {
TResult Function()? loading,
TResult Function()? loaded,
TResult Function(String errorMessage)? error,
required TResult orElse(),
}) {
if ($default != null) {
return $default();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>(
TResult Function(_SettingsState value) $default, {
required TResult Function(SettingsStateLoading value) loading,
required TResult Function(SettingsStateLoaded value) loaded,
required TResult Function(SettingsStateError value) error,
}) {
return $default(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>(
TResult? Function(_SettingsState value)? $default, {
TResult? Function(SettingsStateLoading value)? loading,
TResult? Function(SettingsStateLoaded value)? loaded,
TResult? Function(SettingsStateError value)? error,
}) {
return $default?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>(
TResult Function(_SettingsState value)? $default, {
TResult Function(SettingsStateLoading value)? loading,
TResult Function(SettingsStateLoaded value)? loaded,
TResult Function(SettingsStateError value)? error,
required TResult orElse(),
}) {
if ($default != null) {
return $default(this);
}
return orElse();
}
}
abstract class _SettingsState implements SettingsState {
const factory _SettingsState() = _$SettingsStateImpl;
}
/// @nodoc
abstract class _$$SettingsStateLoadingImplCopyWith<$Res> {
factory _$$SettingsStateLoadingImplCopyWith(_$SettingsStateLoadingImpl value,
$Res Function(_$SettingsStateLoadingImpl) then) =
__$$SettingsStateLoadingImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$SettingsStateLoadingImplCopyWithImpl<$Res>
extends _$SettingsStateCopyWithImpl<$Res, _$SettingsStateLoadingImpl>
implements _$$SettingsStateLoadingImplCopyWith<$Res> {
__$$SettingsStateLoadingImplCopyWithImpl(_$SettingsStateLoadingImpl _value,
$Res Function(_$SettingsStateLoadingImpl) _then)
: super(_value, _then);
/// Create a copy of SettingsState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$SettingsStateLoadingImpl implements SettingsStateLoading {
const _$SettingsStateLoadingImpl();
@override
String toString() {
return 'SettingsState.loading()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$SettingsStateLoadingImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>(
TResult Function() $default, {
required TResult Function() loading,
required TResult Function() loaded,
required TResult Function(String errorMessage) error,
}) {
return loading();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>(
TResult? Function()? $default, {
TResult? Function()? loading,
TResult? Function()? loaded,
TResult? Function(String errorMessage)? error,
}) {
return loading?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>(
TResult Function()? $default, {
TResult Function()? loading,
TResult Function()? loaded,
TResult Function(String errorMessage)? error,
required TResult orElse(),
}) {
if (loading != null) {
return loading();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>(
TResult Function(_SettingsState value) $default, {
required TResult Function(SettingsStateLoading value) loading,
required TResult Function(SettingsStateLoaded value) loaded,
required TResult Function(SettingsStateError value) error,
}) {
return loading(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>(
TResult? Function(_SettingsState value)? $default, {
TResult? Function(SettingsStateLoading value)? loading,
TResult? Function(SettingsStateLoaded value)? loaded,
TResult? Function(SettingsStateError value)? error,
}) {
return loading?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>(
TResult Function(_SettingsState value)? $default, {
TResult Function(SettingsStateLoading value)? loading,
TResult Function(SettingsStateLoaded value)? loaded,
TResult Function(SettingsStateError value)? error,
required TResult orElse(),
}) {
if (loading != null) {
return loading(this);
}
return orElse();
}
}
abstract class SettingsStateLoading implements SettingsState {
const factory SettingsStateLoading() = _$SettingsStateLoadingImpl;
}
/// @nodoc
abstract class _$$SettingsStateLoadedImplCopyWith<$Res> {
factory _$$SettingsStateLoadedImplCopyWith(_$SettingsStateLoadedImpl value,
$Res Function(_$SettingsStateLoadedImpl) then) =
__$$SettingsStateLoadedImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$SettingsStateLoadedImplCopyWithImpl<$Res>
extends _$SettingsStateCopyWithImpl<$Res, _$SettingsStateLoadedImpl>
implements _$$SettingsStateLoadedImplCopyWith<$Res> {
__$$SettingsStateLoadedImplCopyWithImpl(_$SettingsStateLoadedImpl _value,
$Res Function(_$SettingsStateLoadedImpl) _then)
: super(_value, _then);
/// Create a copy of SettingsState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$SettingsStateLoadedImpl implements SettingsStateLoaded {
const _$SettingsStateLoadedImpl();
@override
String toString() {
return 'SettingsState.loaded()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$SettingsStateLoadedImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>(
TResult Function() $default, {
required TResult Function() loading,
required TResult Function() loaded,
required TResult Function(String errorMessage) error,
}) {
return loaded();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>(
TResult? Function()? $default, {
TResult? Function()? loading,
TResult? Function()? loaded,
TResult? Function(String errorMessage)? error,
}) {
return loaded?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>(
TResult Function()? $default, {
TResult Function()? loading,
TResult Function()? loaded,
TResult Function(String errorMessage)? error,
required TResult orElse(),
}) {
if (loaded != null) {
return loaded();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>(
TResult Function(_SettingsState value) $default, {
required TResult Function(SettingsStateLoading value) loading,
required TResult Function(SettingsStateLoaded value) loaded,
required TResult Function(SettingsStateError value) error,
}) {
return loaded(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>(
TResult? Function(_SettingsState value)? $default, {
TResult? Function(SettingsStateLoading value)? loading,
TResult? Function(SettingsStateLoaded value)? loaded,
TResult? Function(SettingsStateError value)? error,
}) {
return loaded?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>(
TResult Function(_SettingsState value)? $default, {
TResult Function(SettingsStateLoading value)? loading,
TResult Function(SettingsStateLoaded value)? loaded,
TResult Function(SettingsStateError value)? error,
required TResult orElse(),
}) {
if (loaded != null) {
return loaded(this);
}
return orElse();
}
}
abstract class SettingsStateLoaded implements SettingsState {
const factory SettingsStateLoaded() = _$SettingsStateLoadedImpl;
}
/// @nodoc
abstract class _$$SettingsStateErrorImplCopyWith<$Res> {
factory _$$SettingsStateErrorImplCopyWith(_$SettingsStateErrorImpl value,
$Res Function(_$SettingsStateErrorImpl) then) =
__$$SettingsStateErrorImplCopyWithImpl<$Res>;
@useResult
$Res call({String errorMessage});
}
/// @nodoc
class __$$SettingsStateErrorImplCopyWithImpl<$Res>
extends _$SettingsStateCopyWithImpl<$Res, _$SettingsStateErrorImpl>
implements _$$SettingsStateErrorImplCopyWith<$Res> {
__$$SettingsStateErrorImplCopyWithImpl(_$SettingsStateErrorImpl _value,
$Res Function(_$SettingsStateErrorImpl) _then)
: super(_value, _then);
/// Create a copy of SettingsState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? errorMessage = null,
}) {
return _then(_$SettingsStateErrorImpl(
errorMessage: null == errorMessage
? _value.errorMessage
: errorMessage // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
/// @nodoc
class _$SettingsStateErrorImpl implements SettingsStateError {
const _$SettingsStateErrorImpl({required this.errorMessage});
@override
final String errorMessage;
@override
String toString() {
return 'SettingsState.error(errorMessage: $errorMessage)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$SettingsStateErrorImpl &&
(identical(other.errorMessage, errorMessage) ||
other.errorMessage == errorMessage));
}
@override
int get hashCode => Object.hash(runtimeType, errorMessage);
/// Create a copy of SettingsState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$SettingsStateErrorImplCopyWith<_$SettingsStateErrorImpl> get copyWith =>
__$$SettingsStateErrorImplCopyWithImpl<_$SettingsStateErrorImpl>(
this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>(
TResult Function() $default, {
required TResult Function() loading,
required TResult Function() loaded,
required TResult Function(String errorMessage) error,
}) {
return error(errorMessage);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>(
TResult? Function()? $default, {
TResult? Function()? loading,
TResult? Function()? loaded,
TResult? Function(String errorMessage)? error,
}) {
return error?.call(errorMessage);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>(
TResult Function()? $default, {
TResult Function()? loading,
TResult Function()? loaded,
TResult Function(String errorMessage)? error,
required TResult orElse(),
}) {
if (error != null) {
return error(errorMessage);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>(
TResult Function(_SettingsState value) $default, {
required TResult Function(SettingsStateLoading value) loading,
required TResult Function(SettingsStateLoaded value) loaded,
required TResult Function(SettingsStateError value) error,
}) {
return error(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>(
TResult? Function(_SettingsState value)? $default, {
TResult? Function(SettingsStateLoading value)? loading,
TResult? Function(SettingsStateLoaded value)? loaded,
TResult? Function(SettingsStateError value)? error,
}) {
return error?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>(
TResult Function(_SettingsState value)? $default, {
TResult Function(SettingsStateLoading value)? loading,
TResult Function(SettingsStateLoaded value)? loaded,
TResult Function(SettingsStateError value)? error,
required TResult orElse(),
}) {
if (error != null) {
return error(this);
}
return orElse();
}
}
abstract class SettingsStateError implements SettingsState {
const factory SettingsStateError({required final String errorMessage}) =
_$SettingsStateErrorImpl;
String get errorMessage;
/// Create a copy of SettingsState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$SettingsStateErrorImplCopyWith<_$SettingsStateErrorImpl> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@@ -1,7 +1,10 @@
import 'package:eatvio_app/core/utils/date_time_utils.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:eatvio_app/theme/theme_helper.dart';
import 'package:eatvio_app/widgets/custom_edit_text_form_field.dart';
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
class GeneralInfoScreen extends StatefulWidget {
const GeneralInfoScreen({super.key});
@@ -13,6 +16,13 @@ class GeneralInfoScreen extends StatefulWidget {
class _GeneralInfoScreenState extends State<GeneralInfoScreen> {
final firstNameController = TextEditingController();
final lastNameController = TextEditingController();
late DateTime selectedDate;
@override
void initState() {
super.initState();
selectedDate = DateTime.now();
}
@override
Widget build(BuildContext context) {
@@ -25,7 +35,7 @@ class _GeneralInfoScreenState extends State<GeneralInfoScreen> {
bottomSheet: _saveButton(),
body: SingleChildScrollView(
physics: const BouncingScrollPhysics(),
padding: EdgeInsets.symmetric(vertical: 16, horizontal: 8),
padding: const EdgeInsets.only(top: 16, bottom: 80, left: 8, right: 8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@@ -33,7 +43,6 @@ class _GeneralInfoScreenState extends State<GeneralInfoScreen> {
SizedBox(height: 4),
CustomTextFormField(
controller: firstNameController,
textInputAction: TextInputAction.next,
hintText: 'Введите имя',
onChanged: (newValue) {},
),
@@ -42,38 +51,113 @@ class _GeneralInfoScreenState extends State<GeneralInfoScreen> {
SizedBox(height: 4),
CustomTextFormField(
controller: lastNameController,
textInputAction: TextInputAction.done,
hintText: 'Введите фамилию',
onChanged: (newValue) {},
),
SizedBox(height: 16),
Text(s.date_of_birth),
SizedBox(height: 4),
CustomTextFormField(
initialValue: selectedDate.format('dd MMMM yyyy', 'ru'),
),
SizedBox(height: 16),
Text('Пол'),
SizedBox(height: 4),
CustomTextFormField(
initialValue: 'Мужской',
onChanged: (newValue) {},
),
SizedBox(height: 16),
Text('Страна'),
SizedBox(height: 4),
CustomTextFormField(
initialValue: 'Россия',
onChanged: (newValue) {},
),
SizedBox(height: 16),
Text('Город'),
SizedBox(height: 4),
CustomTextFormField(
initialValue: 'Москва',
onChanged: (newValue) {},
),
SizedBox(height: 16),
Text('Предпочтительный язык общения'),
SizedBox(height: 4),
CustomTextFormField(
initialValue: 'Русский',
onChanged: (newValue) {},
),
SizedBox(height: 16),
Text('Показывать анкету'),
SizedBox(height: 4),
CustomTextFormField(
initialValue: 'Всем',
onChanged: (newValue) {},
),
],
),
),
);
}
onTapCalendar(BuildContext context) {
return () {
_showDialog(
CupertinoDatePicker(
initialDateTime: selectedDate,
maximumDate: DateTime.now(),
minimumDate: DateTime(1900),
mode: CupertinoDatePickerMode.date,
onDateTimeChanged: (DateTime newDateTime) {
setState(() {
selectedDate = newDateTime;
// final registrationCubit = context.read<RegistrationCubit>();
// registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(birthdate: selectedDate.toString()));
});
},
),
);
};
}
void _showDialog(Widget child) {
showCupertinoModalPopup<void>(
context: context,
builder: (BuildContext context) => Container(
height: 216,
padding: const EdgeInsets.only(top: 6),
margin: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
),
color: CupertinoColors.systemBackground.resolveFrom(context),
child: SafeArea(
top: false,
child: child,
),
),
);
}
_saveButton() {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4),
child: InkWell(
onTap: () {},
borderRadius: BorderRadius.circular(12),
child: Ink(
height: 52,
width: MediaQuery.of(context).size.width - 16,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
color: appTheme.blueA400,
),
child: Center(
child: Text(
'Сохранить',
style: TextStyle(
color: Colors.white,
height: 1,
fontWeight: FontWeight.w600,
fontSize: 18,
),
return InkWell(
onTap: () => GoRouter.of(context).pop(),
borderRadius: BorderRadius.circular(20),
child: Ink(
height: 52,
width: MediaQuery.of(context).size.width - 16,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: appTheme.blueA400,
),
child: Center(
child: Text(
'Сохранить',
style: TextStyle(
color: Colors.white,
height: 1,
fontWeight: FontWeight.w600,
fontSize: 18,
),
),
),

View File

@@ -1,4 +1,4 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class OtherInfoScreen extends StatefulWidget {
const OtherInfoScreen({super.key});
@@ -10,6 +10,6 @@ class OtherInfoScreen extends StatefulWidget {
class _OtherInfoScreenState extends State<OtherInfoScreen> {
@override
Widget build(BuildContext context) {
return const Placeholder();
return Scaffold();
}
}

View File

@@ -1,4 +1,4 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class PhysicalActivityScreen extends StatefulWidget {
const PhysicalActivityScreen({super.key});
@@ -7,9 +7,83 @@ class PhysicalActivityScreen extends StatefulWidget {
State<PhysicalActivityScreen> createState() => _PhysicalActivityScreenState();
}
enum PhysicalActivity { minimum, low, medium, high, extreme, hardWork }
class _PhysicalActivityScreenState extends State<PhysicalActivityScreen> {
PhysicalActivity? _physicalActivity = PhysicalActivity.minimum;
@override
Widget build(BuildContext context) {
return const Placeholder();
return Scaffold(
appBar: AppBar(
title: Text('Физическая нагрузка'),
),
body: SingleChildScrollView(
child: Column(
children: [
RadioListTile<PhysicalActivity>(
title: const Text('1,2 — минимальный (сидячая работа, отсутствие физических нагрузок);'),
value: PhysicalActivity.minimum,
groupValue: _physicalActivity,
onChanged: (PhysicalActivity? value) {
setState(() {
_physicalActivity = value;
});
},
),
RadioListTile<PhysicalActivity>(
title: const Text('1,375 — низкий (тренировки не менее 20 мин 1–3 раза в неделю);'),
value: PhysicalActivity.low,
groupValue: _physicalActivity,
onChanged: (PhysicalActivity? value) {
setState(() {
_physicalActivity = value;
});
},
),
RadioListTile<PhysicalActivity>(
title: const Text('1,55 — умеренный (тренировки 30–60 мин 3–4 раза в неделю);'),
value: PhysicalActivity.medium,
groupValue: _physicalActivity,
onChanged: (PhysicalActivity? value) {
setState(() {
_physicalActivity = value;
});
},
),
RadioListTile<PhysicalActivity>(
title: const Text('1,7 — высокий (тренировки 30–60 мин 5–7 раза в неделю; тяжёлая физическая работа);'),
value: PhysicalActivity.high,
groupValue: _physicalActivity,
onChanged: (PhysicalActivity? value) {
setState(() {
_physicalActivity = value;
});
},
),
RadioListTile<PhysicalActivity>(
title: const Text('1,9 — экстремальный (несколько интенсивных тренировок в день'),
value: PhysicalActivity.extreme,
groupValue: _physicalActivity,
onChanged: (PhysicalActivity? value) {
setState(() {
_physicalActivity = value;
});
},
),
RadioListTile<PhysicalActivity>(
title: const Text('1,9 6–7 раз в неделю; очень трудоёмкая работа).'),
value: PhysicalActivity.hardWork,
groupValue: _physicalActivity,
onChanged: (PhysicalActivity? value) {
setState(() {
_physicalActivity = value;
});
},
),
],
),
),
);
}
}
}

View File

@@ -1,4 +1,9 @@
import 'package:flutter/cupertino.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:eatvio_app/theme/theme_helper.dart';
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:go_router/go_router.dart';
class PhysicalFormScreen extends StatefulWidget {
const PhysicalFormScreen({super.key});
@@ -8,8 +13,79 @@ class PhysicalFormScreen extends StatefulWidget {
}
class _PhysicalFormScreenState extends State<PhysicalFormScreen> {
final digitsOnly = FilteringTextInputFormatter.digitsOnly;
final chestCircumferenceController = TextEditingController();
final waistCircumferenceController = TextEditingController();
final hipCircumferenceController = TextEditingController();
@override
Widget build(BuildContext context) {
return const Placeholder();
final s = S.of(context);
return Scaffold(
appBar: AppBar(
title: Text('Физическая форма'),
),
bottomSheet: _saveButton(),
body: SingleChildScrollView(
physics: const BouncingScrollPhysics(),
padding: EdgeInsets.symmetric(vertical: 16, horizontal: 8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(s.chest_circumference),
SizedBox(height: 4),
CustomTextFormField(
inputFormatters: [digitsOnly],
controller: chestCircumferenceController,
hintText: '90',
),
SizedBox(height: 16),
Text(s.waist_circumference),
SizedBox(height: 4),
CustomTextFormField(
inputFormatters: [digitsOnly],
controller: waistCircumferenceController,
hintText: "60",
),
SizedBox(height: 16),
Text(s.hip_circumference),
SizedBox(height: 4),
CustomTextFormField(
inputFormatters: [digitsOnly],
controller: hipCircumferenceController,
hintText: '90',
textInputAction: TextInputAction.done,
),
],
),
),
);
}
}
_saveButton() {
return InkWell(
onTap: () => GoRouter.of(context).pop(),
borderRadius: BorderRadius.circular(20),
child: Ink(
height: 52,
width: MediaQuery.of(context).size.width - 16,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: appTheme.blueA400,
),
child: Center(
child: Text(
'Сохранить',
style: TextStyle(
color: Colors.white,
height: 1,
fontWeight: FontWeight.w600,
fontSize: 18,
),
),
),
),
);
}
}

View File

@@ -1,4 +1,12 @@
import 'package:flutter/cupertino.dart';
import 'package:eatvio_app/core/utils/image_constant.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:eatvio_app/theme/theme_helper.dart';
import 'package:eatvio_app/widgets/custom_drop_down.dart';
import 'package:eatvio_app/widgets/custom_image_view.dart';
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:go_router/go_router.dart';
class PressureScreen extends StatefulWidget {
const PressureScreen({super.key});
@@ -8,8 +16,110 @@ class PressureScreen extends StatefulWidget {
}
class _PressureScreenState extends State<PressureScreen> {
final digitsOnly = FilteringTextInputFormatter.digitsOnly;
final chestCircumferenceController = TextEditingController();
final waistCircumferenceController = TextEditingController();
final hipCircumferenceController = TextEditingController();
@override
Widget build(BuildContext context) {
return const Placeholder();
final s = S.of(context);
return Scaffold(
appBar: AppBar(
title: Text('Физическая форма'),
),
bottomSheet: _saveButton(),
body: SingleChildScrollView(
physics: const BouncingScrollPhysics(),
padding: EdgeInsets.symmetric(vertical: 16, horizontal: 8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(s.up_pressure),
SizedBox(height: 4),
CustomTextFormField(
inputFormatters: [digitsOnly],
hintText: "90",
onChanged: (newValue) {},
),
SizedBox(height: 16),
Text(s.down_pressure),
SizedBox(height: 4),
CustomTextFormField(
inputFormatters: [digitsOnly],
hintText: '90',
onChanged: (newValue) {},
),
SizedBox(height: 16),
Text(s.do_you_have_hypotension_tendency),
SizedBox(height: 4),
CustomDropDown(
icon: Container(
margin: EdgeInsets.all(16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4),
),
child: CustomImageView(
imagePath: ImageConstant.imgFavorite,
height: 16,
width: 16,
),
),
hintText: "Не выбрано",
onChanged: (newPopup) {
setState(() {});
},
),
SizedBox(height: 16),
Text(s.do_you_have_hypertension_tendency),
SizedBox(height: 4),
CustomDropDown(
icon: Container(
margin: EdgeInsets.all(16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4),
),
child: CustomImageView(
imagePath: ImageConstant.imgFavorite,
height: 16,
width: 16,
),
),
hintText: "Не выбрано",
onChanged: (newPopup) {
setState(() {});
},
),
],
),
),
);
}
}
_saveButton() {
return InkWell(
onTap: () => GoRouter.of(context).pop(),
borderRadius: BorderRadius.circular(20),
child: Ink(
height: 52,
width: MediaQuery.of(context).size.width - 16,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: appTheme.blueA400,
),
child: Center(
child: Text(
'Сохранить',
style: TextStyle(
color: Colors.white,
height: 1,
fontWeight: FontWeight.w600,
fontSize: 18,
),
),
),
),
);
}
}

View File

@@ -1,9 +1,9 @@
import 'package:eatvio_app/data/models/selectionPopupModel/selection_popup_model.dart';
import 'package:eatvio_app/core/const.dart';
import 'package:eatvio_app/theme/theme_helper.dart';
import 'package:eatvio_app/widgets/custom_drop_down.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:url_launcher/url_launcher.dart';
class SettingsScreen extends StatefulWidget {
const SettingsScreen({super.key});
@@ -19,68 +19,35 @@ class _SettingsScreenState extends State<SettingsScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFFF0F2F5),
appBar: AppBar(
title: Text('Настройки'),
),
body: SingleChildScrollView(
padding: EdgeInsets.symmetric(vertical: 16),
physics: const BouncingScrollPhysics(),
child: Column(
children: [
const SizedBox(height: 16),
_selectLanguageDropDown(),
const SizedBox(height: 20),
_additionalInfo(),
const SizedBox(height: 12),
_notifications(),
const SizedBox(height: 12),
_aboutEatvio(),
const SizedBox(height: 16),
const SizedBox(height: 12),
_becomeConsultantButton(),
const SizedBox(height: 8),
_deleteAccountButton(),
const SizedBox(height: 16),
],
),
),
);
}
_selectLanguageDropDown() {
final items = [SelectionPopupModel(title: 'Русский', id: 0, isSelected: true, value: 'Русский')];
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Text(
'Язык',
style: TextStyle(
fontSize: 16,
height: 1,
color: Colors.grey,
),
),
),
const SizedBox(height: 8),
_actionsGroup(
CustomDropDown(
items: items,
value: items[0],
autofocus: false,
),
),
],
);
}
_additionalInfo() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Text(
'Дополнительаная информация',
style: TextStyle(
@@ -91,108 +58,29 @@ class _SettingsScreenState extends State<SettingsScreen> {
),
),
),
const SizedBox(height: 8),
_actionsGroup(
Column(
children: [
const SizedBox(height: 8),
GestureDetector(
onTap: () => GoRouter.of(context).pushNamed('generalInfoScreen'),
child: Row(
children: [
Text(
'Общая информация',
style: TextStyle(
color: Colors.black,
),
),
const Spacer(),
Icon(
Icons.keyboard_arrow_right_rounded,
color: Colors.grey.shade400,
),
],
),
),
_divider(context),
GestureDetector(
onTap: () => GoRouter.of(context).pushNamed('physicalFormScreen'),
child: Row(
children: [
Text(
'Физическая форма',
style: TextStyle(
color: Colors.black,
),
),
const Spacer(),
Icon(
Icons.keyboard_arrow_right_rounded,
color: Colors.grey.shade400,
),
],
),
),
_divider(context),
GestureDetector(
onTap: () => GoRouter.of(context).pushNamed('pressureScreen'),
child: Row(
children: [
Text(
'Давление',
style: TextStyle(
color: Colors.black,
),
),
const Spacer(),
Icon(
Icons.keyboard_arrow_right_rounded,
color: Colors.grey.shade400,
),
],
),
),
_divider(context),
GestureDetector(
onTap: () => GoRouter.of(context).pushNamed('otherInfoScreen'),
child: Row(
children: [
Text(
'Прочая информация',
style: TextStyle(
color: Colors.black,
),
),
const Spacer(),
Icon(
Icons.keyboard_arrow_right_rounded,
color: Colors.grey.shade400,
),
],
),
),
_divider(context),
GestureDetector(
onTap: () => GoRouter.of(context).pushNamed('physicalActivityScreen'),
child: Row(
children: [
Text(
'Физическая нагрузка',
style: TextStyle(
color: Colors.black,
),
),
const Spacer(),
Icon(
Icons.keyboard_arrow_right_rounded,
color: Colors.grey.shade400,
),
],
),
),
const SizedBox(height: 8),
],
),
_tile(
onTap: () => GoRouter.of(context).pushNamed('generalInfoScreen'),
title: 'Общая информация',
),
_divider(context),
_tile(
onTap: () => GoRouter.of(context).pushNamed('physicalFormScreen'),
title: 'Физическая форма',
),
_divider(context),
_tile(
onTap: () => GoRouter.of(context).pushNamed('pressureScreen'),
title: 'Давление',
),
_divider(context),
_tile(
onTap: () => GoRouter.of(context).pushNamed('otherInfoScreen'),
title: 'Прочая информация',
),
_divider(context),
_tile(
onTap: () => GoRouter.of(context).pushNamed('physicalActivityScreen'),
title: 'Физическая нагрузка',
),
],
);
@@ -202,9 +90,8 @@ class _SettingsScreenState extends State<SettingsScreen> {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 8),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Text(
'Уведомления',
style: TextStyle(
@@ -214,55 +101,41 @@ class _SettingsScreenState extends State<SettingsScreen> {
),
),
),
const SizedBox(height: 8),
_actionsGroup(
Column(
children: [
Row(
children: [
Text(
'Уведомление о новых обновлениях',
style: TextStyle(
color: Colors.black,
),
),
const Spacer(),
CupertinoSwitch(
value: updatesNotificationsSwitchState,
activeColor: appTheme.blueA400,
onChanged: (newValue) {
setState(() {
updatesNotificationsSwitchState = newValue;
});
},
),
],
),
_divider(context),
Row(
children: [
Text(
'Напоминание о заполнении дневника',
style: TextStyle(
color: Colors.black,
),
),
const Spacer(),
CupertinoSwitch(
value: fillDiaryNotificationsSwitchState,
activeColor: appTheme.blueA400,
onChanged: (newValue) {
setState(() {
fillDiaryNotificationsSwitchState = newValue;
});
},
),
],
),
],
_tile(
onTap: () {
setState(() {
updatesNotificationsSwitchState = !updatesNotificationsSwitchState;
});
},
title: 'Уведомление о новых обновлениях',
trailing: CupertinoSwitch(
value: updatesNotificationsSwitchState,
activeColor: appTheme.blueA400,
onChanged: (newValue) {
setState(() {
updatesNotificationsSwitchState = newValue;
});
},
),
),
_divider(context),
_tile(
onTap: () {
setState(() {
fillDiaryNotificationsSwitchState = !fillDiaryNotificationsSwitchState;
});
},
title: 'Напоминание о заполнении дневника',
trailing: CupertinoSwitch(
value: fillDiaryNotificationsSwitchState,
activeColor: appTheme.blueA400,
onChanged: (newValue) {
setState(() {
fillDiaryNotificationsSwitchState = newValue;
});
},
),
),
const SizedBox(height: 8),
],
);
}
@@ -272,7 +145,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Text(
'О Eatvio',
style: TextStyle(
@@ -282,45 +155,14 @@ class _SettingsScreenState extends State<SettingsScreen> {
),
),
),
const SizedBox(height: 8),
_actionsGroup(
Column(
children: [
const SizedBox(height: 8),
Row(
children: [
Text(
'О компании',
style: TextStyle(
color: Colors.black,
),
),
const Spacer(),
Icon(
Icons.keyboard_arrow_right_rounded,
color: Colors.grey.shade400,
),
],
),
_divider(context),
Row(
children: [
Text(
'Пользовательское соглашение',
style: TextStyle(
color: Colors.black,
),
),
const Spacer(),
Icon(
Icons.keyboard_arrow_right_rounded,
color: Colors.grey.shade400,
),
],
),
const SizedBox(height: 8),
],
),
_tile(
title: 'О компании',
onTap: () async => await launchUrl(Uri.parse(baseUrl + '/ru/company-details')),
),
_divider(context),
_tile(
title: 'Пользовательское соглашение',
onTap: () async => await launchUrl(Uri.parse(baseUrl + '/oferta_bs.pdf')),
),
],
);
@@ -328,15 +170,15 @@ class _SettingsScreenState extends State<SettingsScreen> {
_becomeConsultantButton() {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 8),
padding: EdgeInsets.symmetric(horizontal: 16),
child: InkWell(
onTap: () {},
borderRadius: BorderRadius.circular(12),
borderRadius: BorderRadius.circular(20),
child: Ink(
height: 52,
width: MediaQuery.of(context).size.width - 16,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
borderRadius: BorderRadius.circular(20),
color: appTheme.blueA400,
),
child: Center(
@@ -357,16 +199,16 @@ class _SettingsScreenState extends State<SettingsScreen> {
_deleteAccountButton() {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 8),
padding: EdgeInsets.symmetric(horizontal: 16),
child: InkWell(
onTap: () {},
borderRadius: BorderRadius.circular(12),
borderRadius: BorderRadius.circular(20),
child: Ink(
height: 52,
width: MediaQuery.of(context).size.width - 16,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
color: Colors.black.withOpacity(0.1),
borderRadius: BorderRadius.circular(20),
color: Color(0xFFEAEAEA),
),
child: Center(
child: Text(
@@ -384,25 +226,39 @@ class _SettingsScreenState extends State<SettingsScreen> {
);
}
_actionsGroup(Widget child) {
return Container(
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 8),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
_tile({
required String title,
required Function() onTap,
Widget? trailing,
}) {
return ListTile(
onTap: onTap,
title: Text(
title,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
height: 1,
),
),
child: child,
trailing: trailing ??
Icon(
Icons.arrow_forward_ios_rounded,
size: 12,
color: Colors.black38,
),
);
}
_divider(BuildContext context) {
return Container(
margin: EdgeInsets.symmetric(vertical: 12),
height: 0.4,
width: MediaQuery.of(context).size.width - 16,
decoration: BoxDecoration(
color: Colors.black26,
borderRadius: BorderRadius.circular(16),
return Center(
child: Container(
height: 0.4,
width: MediaQuery.of(context).size.width - 32,
decoration: BoxDecoration(
color: Colors.black26,
borderRadius: BorderRadius.circular(16),
),
),
);
}

View File

@@ -135,7 +135,7 @@ class _AuthScreenState extends State<AuthScreen> {
elevation: 0,
focusElevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
borderRadius: BorderRadius.circular(20),
),
backgroundColor: appTheme.blueA400,
onPressed: onTapAuth(state, context),

View File

@@ -65,7 +65,7 @@ class ThemeHelper {
width: 1,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
borderRadius: BorderRadius.circular(20),
),
visualDensity: const VisualDensity(
vertical: -4,

View File

@@ -1,10 +1,8 @@
import 'package:eatvio_app/data/models/selectionPopupModel/selection_popup_model.dart';
import 'package:eatvio_app/theme/theme_helper.dart';
import 'package:flutter/material.dart';
class CustomDropDown extends StatelessWidget {
CustomDropDown({
Key? key,
const CustomDropDown({
this.alignment,
this.width,
this.focusNode,
@@ -25,48 +23,27 @@ class CustomDropDown extends StatelessWidget {
this.validator,
this.onChanged,
this.value,
}) : super(
key: key,
);
});
final Alignment? alignment;
final double? width;
final FocusNode? focusNode;
final Widget? icon;
final bool? autofocus;
final TextStyle? textStyle;
final List<SelectionPopupModel>? items;
final String? hintText;
final TextStyle? hintStyle;
final Widget? prefix;
final BoxConstraints? prefixConstraints;
final Widget? suffix;
final BoxConstraints? suffixConstraints;
final EdgeInsets? contentPadding;
final InputBorder? borderDecoration;
final Color? fillColor;
final bool? filled;
final SelectionPopupModel? value;
final FormFieldValidator<SelectionPopupModel>? validator;
final Function(SelectionPopupModel)? onChanged;
@override
@@ -89,7 +66,7 @@ class CustomDropDown extends StatelessWidget {
style: textStyle ??
TextStyle(
fontSize: 16,
fontWeight: FontWeight.w400,
fontWeight: FontWeight.w500,
),
items: items?.map((SelectionPopupModel item) {
return DropdownMenuItem<SelectionPopupModel>(
@@ -99,7 +76,7 @@ class CustomDropDown extends StatelessWidget {
style: hintStyle ??
TextStyle(
fontSize: 16,
fontWeight: FontWeight.w400,
fontWeight: FontWeight.w500,
color: Colors.black,
),
),
@@ -121,41 +98,30 @@ class CustomDropDown extends StatelessWidget {
hintStyle: hintStyle ??
TextStyle(
fontSize: 16,
fontWeight: FontWeight.w400,
fontWeight: FontWeight.w500,
color: Colors.grey.shade400,
height: 1,
),
prefixIcon: prefix,
prefixIconConstraints: prefixConstraints,
suffixIcon: suffix,
suffixIconConstraints: suffixConstraints,
isDense: true,
contentPadding: contentPadding ?? EdgeInsets.all(8),
contentPadding: EdgeInsets.symmetric(vertical: 16, horizontal: 12),
fillColor: fillColor ?? Theme.of(context).colorScheme.onPrimary,
filled: filled,
border: borderDecoration ??
OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(
color: Colors.grey.shade400,
width: 1,
),
),
enabledBorder: borderDecoration ??
OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(
color: Colors.grey.shade400,
width: 1,
),
),
focusedBorder: borderDecoration ??
OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(
color: appTheme.blueA400,
width: 1,
),
),
border: OutlineInputBorder(
borderRadius: const BorderRadius.all(Radius.circular(20)),
borderSide: BorderSide(color: Colors.grey, width: 0.2),
),
enabledBorder: OutlineInputBorder(
borderRadius: const BorderRadius.all(Radius.circular(20)),
borderSide: BorderSide(color: Colors.grey, width: 0.2),
),
focusedBorder: OutlineInputBorder(
borderRadius: const BorderRadius.all(Radius.circular(20)),
borderSide: BorderSide(color: Colors.grey, width: 0.2),
),
);
}
}

View File

@@ -1,145 +0,0 @@
import 'package:eatvio_app/data/models/selectionPopupModel/selection_popup_model.dart';
import 'package:flutter/material.dart';
class CustomDropDown extends StatelessWidget {
CustomDropDown({
Key? key,
this.alignment,
this.width,
this.focusNode,
this.icon,
this.autofocus = true,
this.textStyle,
this.items,
this.hintText,
this.hintStyle,
this.prefix,
this.prefixConstraints,
this.suffix,
this.suffixConstraints,
this.contentPadding,
this.borderDecoration,
this.fillColor,
this.filled = true,
this.validator,
this.onChanged,
this.defaultValue,
}) : super(
key: key,
);
final Alignment? alignment;
final double? width;
final FocusNode? focusNode;
final Widget? icon;
final bool? autofocus;
final TextStyle? textStyle;
final List<SelectionPopupModel>? items;
final String? hintText;
final TextStyle? hintStyle;
final Widget? prefix;
final BoxConstraints? prefixConstraints;
final Widget? suffix;
final BoxConstraints? suffixConstraints;
final EdgeInsets? contentPadding;
final InputBorder? borderDecoration;
final Color? fillColor;
final bool? filled;
final SelectionPopupModel? defaultValue;
final FormFieldValidator<SelectionPopupModel>? validator;
final Function(SelectionPopupModel)? onChanged;
@override
Widget build(BuildContext context) {
return alignment != null
? Align(
alignment: alignment ?? Alignment.center,
child: _buildDropDownWidget(context),
)
: _buildDropDownWidget(context);
}
_buildDropDownWidget(BuildContext context) {
return SizedBox(
width: width ?? double.maxFinite,
child: DropdownButtonFormField<SelectionPopupModel>(
focusNode: focusNode ?? FocusNode(),
icon: icon,
autofocus: autofocus!,
style: textStyle ?? Theme.of(context).textTheme.titleMedium,
items: items?.map((SelectionPopupModel item) {
return DropdownMenuItem<SelectionPopupModel>(
value: item,
child: Text(
item.title,
overflow: TextOverflow.ellipsis,
style: hintStyle ?? Theme.of(context).textTheme.titleMedium,
),
);
}).toList(),
decoration: _buildInputDecoration(context),
validator: validator,
value: defaultValue,
onChanged: onDropDownChanged,
),
);
}
void onDropDownChanged(value) {
onChanged!(value!);
}
InputDecoration _buildInputDecoration(BuildContext context) {
return InputDecoration(
hintText: hintText ?? "",
hintStyle: hintStyle ?? Theme.of(context).textTheme.titleMedium,
prefixIcon: prefix,
prefixIconConstraints: prefixConstraints,
suffixIcon: suffix,
suffixIconConstraints: suffixConstraints,
isDense: true,
contentPadding: contentPadding ??
EdgeInsets.only(
left: 6,
top: 6,
bottom: 6,
),
fillColor: fillColor ?? Theme.of(context).colorScheme.onPrimary,
filled: filled,
border: borderDecoration ??
OutlineInputBorder(
borderRadius: const BorderRadius.all(Radius.circular(8)),
borderSide: BorderSide(color: Colors.grey, width: 1),
),
enabledBorder: borderDecoration ??
OutlineInputBorder(
borderRadius: const BorderRadius.all(Radius.circular(8)),
borderSide: BorderSide(color: Colors.grey, width: 1),
),
focusedBorder: borderDecoration ??
OutlineInputBorder(
borderRadius: const BorderRadius.all(Radius.circular(8)),
borderSide: BorderSide(color: Colors.grey, width: 1),
),
);
}
}

View File

@@ -1,154 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class CustomTextFormField extends StatelessWidget {
CustomTextFormField({
Key? key,
this.alignment,
this.width,
this.controller,
this.focusNode,
this.autofocus = false,
this.textStyle,
this.obscureText = false,
this.textInputAction = TextInputAction.next,
this.textInputType = TextInputType.text,
this.maxLines,
this.hintText,
this.hintStyle,
this.prefix,
this.prefixConstraints,
this.suffix,
this.suffixConstraints,
this.onFieldSubmitted,
this.initialValue,
this.contentPadding,
this.inputFormatters,
this.borderDecoration,
this.fillColor,
this.filled = true,
this.validator,
this.keyboardType,
this.onChanged,
this.onSaved,
}) : super(
key: key,
);
final Alignment? alignment;
final double? width;
final TextEditingController? controller;
final FocusNode? focusNode;
final bool? autofocus;
final TextStyle? textStyle;
final bool? obscureText;
final List<TextInputFormatter>? inputFormatters;
final TextInputAction? textInputAction;
final TextInputType? textInputType;
final int? maxLines;
final String? hintText;
final TextStyle? hintStyle;
final Widget? prefix;
final BoxConstraints? prefixConstraints;
final Widget? suffix;
final Function(String)? onFieldSubmitted;
final BoxConstraints? suffixConstraints;
final EdgeInsets? contentPadding;
final InputBorder? borderDecoration;
final Color? fillColor;
final bool? filled;
final TextInputType? keyboardType;
final String? initialValue;
final FormFieldValidator<String>? validator;
final void Function(String?)? onSaved;
final ValueChanged<String>? onChanged;
@override
Widget build(BuildContext context) {
return alignment != null
? Align(
alignment: alignment ?? Alignment.center,
child: _buildTextFormFieldWidget(context),
)
: _buildTextFormFieldWidget(context);
}
_buildTextFormFieldWidget(BuildContext context) {
return SizedBox(
width: width ?? double.maxFinite,
child: TextFormField(
controller: controller,
focusNode: focusNode ?? FocusNode(),
autofocus: autofocus!,
style: textStyle ?? Theme.of(context).textTheme.titleMedium,
obscureText: obscureText!,
textInputAction: textInputAction,
maxLines: maxLines ?? 1,
decoration: _buildInputDecoration(context),
validator: validator,
keyboardType: keyboardType,
onSaved: onSaved,
onChanged: onChanged,
onFieldSubmitted: onFieldSubmitted,
inputFormatters: inputFormatters,
initialValue: initialValue,
),
);
}
InputDecoration _buildInputDecoration(BuildContext context) {
return InputDecoration(
hintText: hintText ?? "",
hintStyle: hintStyle ?? Theme.of(context).textTheme.bodyLarge,
prefixIcon: prefix,
prefixIconConstraints: prefixConstraints,
suffixIcon: suffix,
suffixIconConstraints: suffixConstraints,
isDense: true,
contentPadding: contentPadding ?? EdgeInsets.all(6),
fillColor: fillColor ?? Theme.of(context).colorScheme.onPrimary,
filled: filled,
border: borderDecoration ??
OutlineInputBorder(
borderRadius: const BorderRadius.all(Radius.circular(8)),
borderSide: BorderSide(color: Colors.grey, width: 1),
),
enabledBorder: borderDecoration ??
OutlineInputBorder(
borderRadius: const BorderRadius.all(Radius.circular(8)),
borderSide: BorderSide(color: Colors.grey, width: 1),
),
focusedBorder: borderDecoration ??
OutlineInputBorder(
borderRadius: const BorderRadius.all(Radius.circular(8)),
borderSide: BorderSide(color: Colors.grey, width: 1),
),
);
}
}

View File

@@ -79,6 +79,7 @@ class CustomTextFormField extends StatelessWidget {
style: TextStyle(
fontSize: 16,
color: Colors.black,
fontWeight: FontWeight.w500,
),
obscureText: obscureText!,
textInputAction: textInputAction,
@@ -89,40 +90,31 @@ class CustomTextFormField extends StatelessWidget {
hintText: hintText ?? "",
hintStyle: TextStyle(
fontSize: 16,
color: Colors.grey.shade400,
fontWeight: FontWeight.w400,
color: Color(0xFF323F4B),
fontWeight: FontWeight.w500,
),
prefixIcon: prefix,
prefixIconConstraints: prefixConstraints,
suffixIcon: suffix,
suffixIconConstraints: suffixConstraints,
isDense: false,
contentPadding: EdgeInsets.all(8),
fillColor: fillColor ?? theme.colorScheme.onPrimary,
filled: filled,
contentPadding: EdgeInsets.symmetric(vertical: 16, horizontal: 12),
fillColor: Color(0xFFF6F6F6),
filled: true,
border: borderDecoration ??
OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: Colors.grey.shade400,
width: 1,
),
borderRadius: BorderRadius.circular(20),
borderSide: BorderSide.none,
),
enabledBorder: borderDecoration ??
OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: Colors.grey.shade400,
width: 1,
),
borderRadius: BorderRadius.circular(20),
borderSide: BorderSide.none,
),
focusedBorder: borderDecoration ??
OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: appTheme.blueA400,
width: 1,
),
borderRadius: BorderRadius.circular(20),
borderSide: BorderSide.none,
),
),
keyboardType: keyboardType,