diff --git a/lib/features/create_diet/presentation/create_diet_screen.dart b/lib/features/create_diet/presentation/create_diet_screen.dart index b77ac3b9..2497b633 100644 --- a/lib/features/create_diet/presentation/create_diet_screen.dart +++ b/lib/features/create_diet/presentation/create_diet_screen.dart @@ -58,6 +58,39 @@ class _CreateDietScreenContentState extends State { final GlobalKey _mdKey = GlobalKey(); bool _mdToolbarVisible = false; + final GlobalKey _nameKey = GlobalKey(); + final GlobalKey _durationKey = GlobalKey(); + final GlobalKey _statusKey = GlobalKey(); + final GlobalKey _typeKey = GlobalKey(); + final GlobalKey _imageKey = GlobalKey(); + final GlobalKey _planKey = GlobalKey(); + + void _scrollToFirstError(CreateDietState state) { + GlobalKey? key; + if (state.dietNameError != null) { + key = _nameKey; + } else if (state.dietDescriptionError != null) { + key = _mdKey; + } else if (state.dietDurationError != null) { + key = _durationKey; + } else if (state.dietStateError != null) { + key = _statusKey; + } else if (state.dietImageError != null) { + key = _imageKey; + } else if (state.dailyScheduleErrors.any((e) => e.isNotEmpty)) { + key = _planKey; + } + + if (key != null && key.currentContext != null) { + Scrollable.ensureVisible( + key.currentContext!, + duration: const Duration(milliseconds: 500), + curve: Curves.easeInOut, + alignment: 0.1, + ); + } + } + @override void initState() { super.initState(); @@ -118,6 +151,7 @@ class _CreateDietScreenContentState extends State { children: [ const SizedBox(height: 16), CustomTextFormField( + key: _nameKey, hintText: s.enter_diet_name, controller: nameController, hasError: state.dietNameError != null, @@ -143,19 +177,20 @@ class _CreateDietScreenContentState extends State { ), if (state.dietDescriptionError != null) ...[const SizedBox(height: 4), ValidationErrorWidget(error: state.dietDescriptionError ?? '')], const SizedBox(height: 12), - const DietDurationDropDownWidget(), + DietDurationDropDownWidget(key: _durationKey), const SizedBox(height: 12), - StatusDropDownWidget(dietState: widget.diet?.state), + StatusDropDownWidget(key: _statusKey, dietState: widget.diet?.state), const SizedBox(height: 16), - const DietTypeChoiceWidget(), + DietTypeChoiceWidget(key: _typeKey), const SizedBox(height: 16), - const DietImagePickerWidget(), + DietImagePickerWidget(key: _imageKey), const SizedBox(height: 16), ], ), ), const SizedBox(height: 16), MainBackgroundBouble( + key: _planKey, child: Padding( padding: const EdgeInsets.symmetric(vertical: 16.0), child: Center( @@ -185,7 +220,11 @@ class _CreateDietScreenContentState extends State { ? () {} : () async { final diet = await context.read().getDietForPreview(); - if (diet == null) return; + if (diet == null) { + // ignore: use_build_context_synchronously + _scrollToFirstError(context.read().state); + return; + } if (!context.mounted) return; GoRouter.of(context).pushNamed(DietPreviewScreen.name, extra: diet); }, @@ -204,7 +243,10 @@ class _CreateDietScreenContentState extends State { CustomOutlinedButton( onPressed: () async { final result = await context.read().createDiet(); - if (result == 'error') { + if (result == 'validation') { + // ignore: use_build_context_synchronously + _scrollToFirstError(context.read().state); + } else if (result == 'error') { if (!context.mounted) return; showErrorDialog(context, title: '${s.could_not_publish_diet} ${state.dietData.name}'); } diff --git a/lib/features/create_diet/presentation/cubit/create_diet_cubit.dart b/lib/features/create_diet/presentation/cubit/create_diet_cubit.dart index 8ecf89ba..f8eb5a73 100644 --- a/lib/features/create_diet/presentation/cubit/create_diet_cubit.dart +++ b/lib/features/create_diet/presentation/cubit/create_diet_cubit.dart @@ -394,11 +394,11 @@ class CreateDietCubit extends Cubit { result = false; emit(state.copyWith(dietStateError: 'Статус диеты не выбран')); } - if (state.dietData.image == null) { + if (state.dietData.image == null && state.dietData.imageUrl == null) { result = false; emit(state.copyWith(dietImageError: 'Не добавлена обложка')); } - result = _isDailyScheduleValid(); + result = _isDailyScheduleValid() && result; return result; }