forked from eatvio/eatvio_app
fixed profile, recipeis and diets
This commit is contained in:
@@ -6,6 +6,7 @@ import 'package:eatvio_app/core/widgets/bottom_sheet_handler_bar.dart';
|
||||
import 'package:eatvio_app/core/widgets/bottom_sheet_with_blur.dart';
|
||||
import 'package:eatvio_app/core/widgets/custom_outlined_button.dart';
|
||||
import 'package:eatvio_app/core/widgets/custom_text_form_field.dart';
|
||||
import 'package:eatvio_app/core/widgets/loader.dart';
|
||||
import 'package:eatvio_app/core/widgets/main_background_bouble.dart';
|
||||
import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_cubit.dart';
|
||||
import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_state.dart';
|
||||
@@ -16,6 +17,7 @@ import 'package:eatvio_app/features/create_diet/presentation/widgets/diet_image_
|
||||
import 'package:eatvio_app/features/create_diet/presentation/widgets/error_widget.dart';
|
||||
import 'package:eatvio_app/features/create_diet/presentation/widgets/status_drop_down_widget.dart';
|
||||
import 'package:eatvio_app/features/create_diet/presentation/widgets/diet_type_choice_widget.dart';
|
||||
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
|
||||
import 'package:eatvio_app/generated/l10n.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
@@ -24,19 +26,37 @@ import 'package:go_router/go_router.dart';
|
||||
class CreateDietScreen extends StatelessWidget {
|
||||
static const name = 'createDietScreen';
|
||||
static const path = '/create-diet-screen';
|
||||
const CreateDietScreen({super.key});
|
||||
|
||||
const CreateDietScreen({super.key, this.diet});
|
||||
final Diet? diet;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => sl<CreateDietCubit>(),
|
||||
child: const CreateDietScreenContent(),
|
||||
create: (context) => sl<CreateDietCubit>()..setInitialData(diet),
|
||||
child: CreateDietScreenContent(diet: diet),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class CreateDietScreenContent extends StatelessWidget {
|
||||
const CreateDietScreenContent({super.key});
|
||||
class CreateDietScreenContent extends StatefulWidget {
|
||||
CreateDietScreenContent({super.key, this.diet});
|
||||
final Diet? diet;
|
||||
|
||||
@override
|
||||
State<CreateDietScreenContent> createState() => _CreateDietScreenContentState();
|
||||
}
|
||||
|
||||
class _CreateDietScreenContentState extends State<CreateDietScreenContent> {
|
||||
final nameController = TextEditingController();
|
||||
final descriptionController = TextEditingController();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (widget.diet != null) {
|
||||
nameController.text = widget.diet?.name ?? '';
|
||||
descriptionController.text = widget.diet?.details ?? '';
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -44,55 +64,12 @@ class CreateDietScreenContent extends StatelessWidget {
|
||||
return BlocBuilder<CreateDietCubit, CreateDietState>(
|
||||
builder: (context, state) {
|
||||
if (state.published) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
context.pop();
|
||||
showBottomSheetWithBlur(
|
||||
context: context,
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
BottomSheetHandlerBar(),
|
||||
SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Text(
|
||||
'${state.dietData.name ?? 'Диета'}',
|
||||
style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black),
|
||||
),
|
||||
Text(
|
||||
'опубликованна',
|
||||
style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black),
|
||||
),
|
||||
SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||
child: CustomOutlinedButton(
|
||||
onPressed: () {
|
||||
context.pop();
|
||||
},
|
||||
text: 'Хорошо',
|
||||
height: 52,
|
||||
buttonTextStyle: TextStyles.textSSemibold.copyWith(color: appTheme.whiteA700),
|
||||
buttonStyle: ButtonStyle(
|
||||
side: WidgetStatePropertyAll(BorderSide.none),
|
||||
backgroundColor: WidgetStatePropertyAll(appTheme.blueA400),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
Future.delayed(Duration(milliseconds: 500), () {
|
||||
context.pop('${state.dietData.name ?? 'Диета'}');
|
||||
});
|
||||
} else if (state.drafted) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
context.pop();
|
||||
Future.delayed(Duration(milliseconds: 500), () {
|
||||
context.pop('${state.dietData.name ?? 'Диета'}');
|
||||
showBottomSheetWithBlur(
|
||||
context: context,
|
||||
child: Column(
|
||||
@@ -116,7 +93,7 @@ class CreateDietScreenContent extends StatelessWidget {
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||
child: CustomOutlinedButton(
|
||||
onPressed: () {
|
||||
context.pop();
|
||||
Navigator.of(context, rootNavigator: true).pop();
|
||||
},
|
||||
text: 'Хорошо',
|
||||
height: 52,
|
||||
@@ -141,7 +118,7 @@ class CreateDietScreenContent extends StatelessWidget {
|
||||
appBar: AppBar(
|
||||
centerTitle: true,
|
||||
title: Text(
|
||||
s.create_diet,
|
||||
widget.diet != null ? 'Редактирование диеты' : s.create_diet,
|
||||
textAlign: TextAlign.center,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: true,
|
||||
@@ -160,6 +137,7 @@ class CreateDietScreenContent extends StatelessWidget {
|
||||
SizedBox(height: 16),
|
||||
CustomTextFormField(
|
||||
hintText: s.enter_diet_name,
|
||||
controller: nameController,
|
||||
hasError: state.dietNameError != null,
|
||||
onChanged: (value) {
|
||||
context.read<CreateDietCubit>().setName(value);
|
||||
@@ -176,6 +154,7 @@ class CreateDietScreenContent extends StatelessWidget {
|
||||
height: 132,
|
||||
child: CustomTextFormField(
|
||||
hasError: state.dietDescriptionError != null,
|
||||
controller: descriptionController,
|
||||
textAlignVertical: TextAlignVertical.top,
|
||||
maxLines: null,
|
||||
minLines: null,
|
||||
@@ -227,30 +206,19 @@ class CreateDietScreenContent extends StatelessWidget {
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
separatorBuilder: (context, index) => SizedBox(height: 8),
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
SizedBox(height: 12),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||
child: Column(
|
||||
children: [
|
||||
CustomOutlinedButton(
|
||||
onPressed: () async {
|
||||
await context.read<CreateDietCubit>().publishDiet(toDraft: true);
|
||||
},
|
||||
text: s.to_draft,
|
||||
height: 52,
|
||||
buttonTextStyle: TextStyles.textMSemibold.copyWith(color: appTheme.gray),
|
||||
buttonStyle: ButtonStyle(
|
||||
side: WidgetStatePropertyAll(BorderSide.none),
|
||||
backgroundColor: WidgetStatePropertyAll(appTheme.dottedBorder),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 12),
|
||||
CustomOutlinedButton(
|
||||
onPressed: () async {
|
||||
final diet = await context.read<CreateDietCubit>().getDietForPreview();
|
||||
if (diet == null) return;
|
||||
GoRouter.of(context).pushNamed(DietPreviewScreen.name, extra: diet);
|
||||
},
|
||||
onPressed: state.isDietPublishing
|
||||
? () {}
|
||||
: () async {
|
||||
final diet = await context.read<CreateDietCubit>().getDietForPreview();
|
||||
if (diet == null) return;
|
||||
GoRouter.of(context).pushNamed(DietPreviewScreen.name, extra: diet);
|
||||
},
|
||||
text: s.preview,
|
||||
height: 52,
|
||||
buttonTextStyle: TextStyles.textMSemibold.copyWith(color: appTheme.gray),
|
||||
@@ -260,18 +228,21 @@ class CreateDietScreenContent extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
SizedBox(height: 12),
|
||||
CustomOutlinedButton(
|
||||
onPressed: () {
|
||||
context.read<CreateDietCubit>().publishDiet();
|
||||
},
|
||||
text: s.publish,
|
||||
height: 52,
|
||||
buttonTextStyle: TextStyles.textMSemibold.copyWith(color: appTheme.whiteA700),
|
||||
buttonStyle: ButtonStyle(
|
||||
side: WidgetStatePropertyAll(BorderSide.none),
|
||||
backgroundColor: WidgetStatePropertyAll(appTheme.blueA400),
|
||||
if (state.isDietPublishing)
|
||||
Loader()
|
||||
else
|
||||
CustomOutlinedButton(
|
||||
onPressed: () {
|
||||
context.read<CreateDietCubit>().publishDiet();
|
||||
},
|
||||
text: widget.diet != null ? s.save : s.publish,
|
||||
height: 52,
|
||||
buttonTextStyle: TextStyles.textMSemibold.copyWith(color: appTheme.whiteA700),
|
||||
buttonStyle: ButtonStyle(
|
||||
side: WidgetStatePropertyAll(BorderSide.none),
|
||||
backgroundColor: WidgetStatePropertyAll(appTheme.blueA400),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -282,5 +253,5 @@ class CreateDietScreenContent extends StatelessWidget {
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:developer';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:eatvio_app/core/const.dart';
|
||||
import 'package:eatvio_app/core/image_compressing/image_compress_utility.dart';
|
||||
import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_state.dart';
|
||||
@@ -16,10 +17,46 @@ class CreateDietCubit extends Cubit<CreateDietState> {
|
||||
final CreateDietRepository createDietRepository;
|
||||
final ProfileRepository profileRepository;
|
||||
final GlossaryRepository glossaryRepository;
|
||||
static const _dietStateValues = ['active', 'personal', 'draft'];
|
||||
String? tempImagePath;
|
||||
static const _dietStateValues = DietState.values;
|
||||
|
||||
CreateDietCubit({required this.profileRepository, required this.createDietRepository, required this.glossaryRepository}) : super(CreateDietState.initial());
|
||||
|
||||
Future<void> setInitialData(Diet? diet) async {
|
||||
if (diet == null) return;
|
||||
emit(state.copyWith(isLoading: true, isDietBeingEdited: true));
|
||||
final countOfDays = diet.dailySchedule.length;
|
||||
final List<List<List<DailySchedule>>> dailySchedule = List.generate(countOfDays, (index) => [[], [], [], [], []]);
|
||||
|
||||
for (final dayEntry in diet.dailySchedule.entries) {
|
||||
for (final mealEntry in dayEntry.value.entries) {
|
||||
for (final product in mealEntry.value.values) {
|
||||
dailySchedule[dayEntry.key - 1][mealEntry.key - 1].add(product);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final dietStateIndex = _dietStateValues.indexOf(diet.state);
|
||||
final type = Map<String, bool>.fromIterable(dietTypeValues, value: (element) => false);
|
||||
type['meat'] = diet.type.meat ?? false;
|
||||
type['veg'] = diet.type.veg ?? false;
|
||||
type['carb'] = diet.type.carb ?? false;
|
||||
type['light'] = diet.type.light ?? false;
|
||||
emit(
|
||||
state.copyWith.dietData(
|
||||
dailySchedule: dailySchedule,
|
||||
details: diet.details,
|
||||
state: diet.state,
|
||||
name: diet.name,
|
||||
duration: diet.duration,
|
||||
type: type,
|
||||
imageUrl: baseUrl + '/storage/' + diet.image,
|
||||
),
|
||||
);
|
||||
emit(state.copyWith(dietStateIndex: dietStateIndex, durationIndex: durationValues.indexOf(diet.duration)));
|
||||
emit(state.copyWith(isLoading: true));
|
||||
}
|
||||
|
||||
void setDetails(String text) {
|
||||
emit(state.copyWith(dietData: state.dietData.copyWith(details: text), dietDescriptionError: null));
|
||||
}
|
||||
@@ -82,16 +119,16 @@ class CreateDietCubit extends Cubit<CreateDietState> {
|
||||
return await glossaryRepository.getGlossaryListByQuery(query);
|
||||
}
|
||||
|
||||
void setImage(XFile? image) {
|
||||
emit(state.copyWith(dietData: state.dietData.copyWith(image: image), dietImageError: null));
|
||||
void setImage(XFile? image, {String? imageUrl}) {
|
||||
emit(state.copyWith(dietData: state.dietData.copyWith(image: image, imageUrl: imageUrl), dietImageError: null));
|
||||
}
|
||||
|
||||
void setDailySchedule(List<List<List<DailySchedule>>> dailySchedule) {
|
||||
emit(state.copyWith(dietData: state.dietData.copyWith(dailySchedule: dailySchedule), dietDurationError: null));
|
||||
}
|
||||
|
||||
void setDietState(int index) {
|
||||
emit(state.copyWith(dietStateIndex: index, dietData: state.dietData.copyWith(state: _dietStateValues[index]), dietStateError: null));
|
||||
void setDietState(DietState dietState, int index) {
|
||||
emit(state.copyWith(dietData: state.dietData.copyWith(state: dietState), dietStateIndex: index, dietStateError: null));
|
||||
}
|
||||
|
||||
void setDietType({required String key, required bool value}) {
|
||||
@@ -236,12 +273,26 @@ class CreateDietCubit extends Cubit<CreateDietState> {
|
||||
);
|
||||
}
|
||||
}
|
||||
final dailySchedule = <int, Map<int, Map<int, DailySchedule>>>{};
|
||||
|
||||
for (final (dayIndex, day) in state.dietData.dailySchedule!.indexed) {
|
||||
final mappedDay = <int, Map<int, DailySchedule>>{};
|
||||
for (final (mealIndex, meal) in day.indexed) {
|
||||
final mappedMeal = <int, DailySchedule>{};
|
||||
for (final (productIndex, product) in meal.indexed) {
|
||||
mappedMeal[productIndex + 1] = product;
|
||||
}
|
||||
mappedDay[mealIndex + 1] = mappedMeal;
|
||||
}
|
||||
dailySchedule[dayIndex + 1] = mappedDay;
|
||||
}
|
||||
|
||||
final diet = Diet(
|
||||
id: 0,
|
||||
name: state.dietData.name ?? '',
|
||||
image: imageInBase64,
|
||||
duration: state.dietData.duration ?? 0,
|
||||
state: state.dietData.state ?? '',
|
||||
state: state.dietData.state ?? DietState.active,
|
||||
type: DietType(
|
||||
meat: state.dietData.type['meat'],
|
||||
veg: state.dietData.type['veg'],
|
||||
@@ -249,7 +300,7 @@ class CreateDietCubit extends Cubit<CreateDietState> {
|
||||
light: state.dietData.type['light'],
|
||||
),
|
||||
details: state.dietData.details ?? '',
|
||||
dailySchedule: state.dietData.dailySchedule ?? [],
|
||||
dailySchedule: dailySchedule,
|
||||
author: Author(
|
||||
authorSlug: authorProfile.slug,
|
||||
authorName: authorProfile.name,
|
||||
@@ -267,32 +318,32 @@ class CreateDietCubit extends Cubit<CreateDietState> {
|
||||
return diet;
|
||||
}
|
||||
|
||||
Future<String?> publishDiet({bool toDraft = false}) async {
|
||||
Future<String?> publishDiet() async {
|
||||
emit(state.copyWith(isDietPublishing: true));
|
||||
if (!_isFromValid()) return null;
|
||||
try {
|
||||
final image = await ImageCompressUtility.compressFile(File(state.dietData.image!.path));
|
||||
final dietState = toDraft ? _dietStateValues.last : state.dietData.state;
|
||||
final diet = await createDietRepository.createDiet(
|
||||
name: state.dietData.name,
|
||||
duration: state.dietData.duration,
|
||||
final dietState = state.dietData.state!;
|
||||
final dailySchedule = state.dietData.dailySchedule;
|
||||
await createDietRepository.createDiet(
|
||||
name: state.dietData.name ?? '',
|
||||
duration: state.dietData.duration ?? 7,
|
||||
state: dietState,
|
||||
image: image,
|
||||
meatType: state.dietData.type['meat'] == true ? '1' : '0',
|
||||
carbType: state.dietData.type['carb'] == true ? '1' : '0',
|
||||
vegType: state.dietData.type['veg'] == true ? '1' : '0',
|
||||
lightType: state.dietData.type['light'] == true ? '1' : '0',
|
||||
details: state.dietData.details,
|
||||
details: state.dietData.details ?? '',
|
||||
dailySchedule: dailySchedule ?? [],
|
||||
);
|
||||
final dailySchedule = state.dietData.dailySchedule;
|
||||
createDietRepository.createDietDailySchedule(
|
||||
id: diet.id,
|
||||
model: {'daily_schedule': dailySchedule},
|
||||
);
|
||||
emit(state.copyWith(published: !toDraft, drafted: toDraft));
|
||||
|
||||
emit(state.copyWith(published: dietState != DietState.draft, drafted: dietState == DietState.draft));
|
||||
return state.dietData.name;
|
||||
} catch (e, stackTrace) {
|
||||
} on DioException catch (e, stackTrace) {
|
||||
log(e.toString(), stackTrace: stackTrace);
|
||||
}
|
||||
emit(state.copyWith(isDietPublishing: false));
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -336,15 +387,11 @@ class CreateDietCubit extends Cubit<CreateDietState> {
|
||||
if (dailySchedule == null) {
|
||||
result = false;
|
||||
} else {
|
||||
final dailyScheduleErrors = state.dailyScheduleErrors.map((element) {
|
||||
return element.map((element) => element).toList();
|
||||
}).toList();
|
||||
final dailyScheduleErrors = [...state.dailyScheduleErrors];
|
||||
for (final (dayIndex, day) in dailySchedule.indexed) {
|
||||
for (final (mealIndex, meal) in day.indexed) {
|
||||
if (meal.isEmpty) {
|
||||
result = false;
|
||||
dailyScheduleErrors[dayIndex][mealIndex] = 'Добавьте продукты';
|
||||
}
|
||||
if (day.every((meal) => meal.isEmpty)) {
|
||||
result = false;
|
||||
dailyScheduleErrors[dayIndex] = 'Добавьте продукты';
|
||||
}
|
||||
}
|
||||
emit(state.copyWith(dailyScheduleErrors: dailyScheduleErrors));
|
||||
@@ -358,16 +405,13 @@ class CreateDietCubit extends Cubit<CreateDietState> {
|
||||
if (dailySchedule == null) {
|
||||
result = false;
|
||||
} else {
|
||||
final dailyScheduleErrors = state.dailyScheduleErrors.map((element) {
|
||||
return element.map((element) => element).toList();
|
||||
}).toList();
|
||||
for (final (mealIndex, meal) in dailySchedule[dayIndex].indexed) {
|
||||
if (meal.isEmpty) {
|
||||
result = false;
|
||||
dailyScheduleErrors[dayIndex][mealIndex] = 'Добавьте продукты';
|
||||
} else {
|
||||
dailyScheduleErrors[dayIndex][mealIndex] = '';
|
||||
}
|
||||
final dailyScheduleErrors = [...state.dailyScheduleErrors];
|
||||
final day = dailySchedule[dayIndex];
|
||||
if (day.every((meal) => meal.isEmpty)) {
|
||||
result = false;
|
||||
dailyScheduleErrors[dayIndex] = 'Добавьте продукты';
|
||||
} else {
|
||||
dailyScheduleErrors[dayIndex] = '';
|
||||
}
|
||||
emit(state.copyWith(dailyScheduleErrors: dailyScheduleErrors));
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ part 'create_diet_state.freezed.dart';
|
||||
class CreateDietState with _$CreateDietState {
|
||||
const factory CreateDietState({
|
||||
required bool isLoading,
|
||||
required bool isDietPublishing,
|
||||
required String? errorMessage,
|
||||
required CreateDietModel dietData,
|
||||
List<List<DailySchedule>>? copiedDay,
|
||||
@@ -17,15 +18,17 @@ class CreateDietState with _$CreateDietState {
|
||||
String? dietDurationError,
|
||||
String? dietStateError,
|
||||
String? dietImageError,
|
||||
required List<List<String>> dailyScheduleErrors,
|
||||
required List<String> dailyScheduleErrors,
|
||||
int? durationIndex,
|
||||
int? dietStateIndex,
|
||||
@Default(false) bool published,
|
||||
@Default(false) bool drafted,
|
||||
@Default(false) bool isDietBeingEdited,
|
||||
}) = _CreateDietState;
|
||||
|
||||
factory CreateDietState.initial() => CreateDietState(
|
||||
dailyScheduleErrors: List.filled(21, ['', '', '', '', '']),
|
||||
dailyScheduleErrors: List.filled(21, ''),
|
||||
isDietPublishing: false,
|
||||
isLoading: false,
|
||||
errorMessage: null,
|
||||
dietData: CreateDietModel(
|
||||
|
||||
@@ -17,6 +17,7 @@ final _privateConstructorUsedError = UnsupportedError(
|
||||
/// @nodoc
|
||||
mixin _$CreateDietState {
|
||||
bool get isLoading => throw _privateConstructorUsedError;
|
||||
bool get isDietPublishing => throw _privateConstructorUsedError;
|
||||
String? get errorMessage => throw _privateConstructorUsedError;
|
||||
CreateDietModel get dietData => throw _privateConstructorUsedError;
|
||||
List<List<DailySchedule>>? get copiedDay =>
|
||||
@@ -26,12 +27,12 @@ mixin _$CreateDietState {
|
||||
String? get dietDurationError => throw _privateConstructorUsedError;
|
||||
String? get dietStateError => throw _privateConstructorUsedError;
|
||||
String? get dietImageError => throw _privateConstructorUsedError;
|
||||
List<List<String>> get dailyScheduleErrors =>
|
||||
throw _privateConstructorUsedError;
|
||||
List<String> get dailyScheduleErrors => throw _privateConstructorUsedError;
|
||||
int? get durationIndex => throw _privateConstructorUsedError;
|
||||
int? get dietStateIndex => throw _privateConstructorUsedError;
|
||||
bool get published => throw _privateConstructorUsedError;
|
||||
bool get drafted => throw _privateConstructorUsedError;
|
||||
bool get isDietBeingEdited => throw _privateConstructorUsedError;
|
||||
|
||||
/// Create a copy of CreateDietState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@@ -48,6 +49,7 @@ abstract class $CreateDietStateCopyWith<$Res> {
|
||||
@useResult
|
||||
$Res call(
|
||||
{bool isLoading,
|
||||
bool isDietPublishing,
|
||||
String? errorMessage,
|
||||
CreateDietModel dietData,
|
||||
List<List<DailySchedule>>? copiedDay,
|
||||
@@ -56,11 +58,12 @@ abstract class $CreateDietStateCopyWith<$Res> {
|
||||
String? dietDurationError,
|
||||
String? dietStateError,
|
||||
String? dietImageError,
|
||||
List<List<String>> dailyScheduleErrors,
|
||||
List<String> dailyScheduleErrors,
|
||||
int? durationIndex,
|
||||
int? dietStateIndex,
|
||||
bool published,
|
||||
bool drafted});
|
||||
bool drafted,
|
||||
bool isDietBeingEdited});
|
||||
|
||||
$CreateDietModelCopyWith<$Res> get dietData;
|
||||
}
|
||||
@@ -81,6 +84,7 @@ class _$CreateDietStateCopyWithImpl<$Res, $Val extends CreateDietState>
|
||||
@override
|
||||
$Res call({
|
||||
Object? isLoading = null,
|
||||
Object? isDietPublishing = null,
|
||||
Object? errorMessage = freezed,
|
||||
Object? dietData = null,
|
||||
Object? copiedDay = freezed,
|
||||
@@ -94,12 +98,17 @@ class _$CreateDietStateCopyWithImpl<$Res, $Val extends CreateDietState>
|
||||
Object? dietStateIndex = freezed,
|
||||
Object? published = null,
|
||||
Object? drafted = null,
|
||||
Object? isDietBeingEdited = null,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
isLoading: null == isLoading
|
||||
? _value.isLoading
|
||||
: isLoading // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
isDietPublishing: null == isDietPublishing
|
||||
? _value.isDietPublishing
|
||||
: isDietPublishing // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
errorMessage: freezed == errorMessage
|
||||
? _value.errorMessage
|
||||
: errorMessage // ignore: cast_nullable_to_non_nullable
|
||||
@@ -135,7 +144,7 @@ class _$CreateDietStateCopyWithImpl<$Res, $Val extends CreateDietState>
|
||||
dailyScheduleErrors: null == dailyScheduleErrors
|
||||
? _value.dailyScheduleErrors
|
||||
: dailyScheduleErrors // ignore: cast_nullable_to_non_nullable
|
||||
as List<List<String>>,
|
||||
as List<String>,
|
||||
durationIndex: freezed == durationIndex
|
||||
? _value.durationIndex
|
||||
: durationIndex // ignore: cast_nullable_to_non_nullable
|
||||
@@ -152,6 +161,10 @@ class _$CreateDietStateCopyWithImpl<$Res, $Val extends CreateDietState>
|
||||
? _value.drafted
|
||||
: drafted // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
isDietBeingEdited: null == isDietBeingEdited
|
||||
? _value.isDietBeingEdited
|
||||
: isDietBeingEdited // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
) as $Val);
|
||||
}
|
||||
|
||||
@@ -176,6 +189,7 @@ abstract class _$$CreateDietStateImplCopyWith<$Res>
|
||||
@useResult
|
||||
$Res call(
|
||||
{bool isLoading,
|
||||
bool isDietPublishing,
|
||||
String? errorMessage,
|
||||
CreateDietModel dietData,
|
||||
List<List<DailySchedule>>? copiedDay,
|
||||
@@ -184,11 +198,12 @@ abstract class _$$CreateDietStateImplCopyWith<$Res>
|
||||
String? dietDurationError,
|
||||
String? dietStateError,
|
||||
String? dietImageError,
|
||||
List<List<String>> dailyScheduleErrors,
|
||||
List<String> dailyScheduleErrors,
|
||||
int? durationIndex,
|
||||
int? dietStateIndex,
|
||||
bool published,
|
||||
bool drafted});
|
||||
bool drafted,
|
||||
bool isDietBeingEdited});
|
||||
|
||||
@override
|
||||
$CreateDietModelCopyWith<$Res> get dietData;
|
||||
@@ -208,6 +223,7 @@ class __$$CreateDietStateImplCopyWithImpl<$Res>
|
||||
@override
|
||||
$Res call({
|
||||
Object? isLoading = null,
|
||||
Object? isDietPublishing = null,
|
||||
Object? errorMessage = freezed,
|
||||
Object? dietData = null,
|
||||
Object? copiedDay = freezed,
|
||||
@@ -221,12 +237,17 @@ class __$$CreateDietStateImplCopyWithImpl<$Res>
|
||||
Object? dietStateIndex = freezed,
|
||||
Object? published = null,
|
||||
Object? drafted = null,
|
||||
Object? isDietBeingEdited = null,
|
||||
}) {
|
||||
return _then(_$CreateDietStateImpl(
|
||||
isLoading: null == isLoading
|
||||
? _value.isLoading
|
||||
: isLoading // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
isDietPublishing: null == isDietPublishing
|
||||
? _value.isDietPublishing
|
||||
: isDietPublishing // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
errorMessage: freezed == errorMessage
|
||||
? _value.errorMessage
|
||||
: errorMessage // ignore: cast_nullable_to_non_nullable
|
||||
@@ -262,7 +283,7 @@ class __$$CreateDietStateImplCopyWithImpl<$Res>
|
||||
dailyScheduleErrors: null == dailyScheduleErrors
|
||||
? _value._dailyScheduleErrors
|
||||
: dailyScheduleErrors // ignore: cast_nullable_to_non_nullable
|
||||
as List<List<String>>,
|
||||
as List<String>,
|
||||
durationIndex: freezed == durationIndex
|
||||
? _value.durationIndex
|
||||
: durationIndex // ignore: cast_nullable_to_non_nullable
|
||||
@@ -279,6 +300,10 @@ class __$$CreateDietStateImplCopyWithImpl<$Res>
|
||||
? _value.drafted
|
||||
: drafted // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
isDietBeingEdited: null == isDietBeingEdited
|
||||
? _value.isDietBeingEdited
|
||||
: isDietBeingEdited // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -288,6 +313,7 @@ class __$$CreateDietStateImplCopyWithImpl<$Res>
|
||||
class _$CreateDietStateImpl implements _CreateDietState {
|
||||
const _$CreateDietStateImpl(
|
||||
{required this.isLoading,
|
||||
required this.isDietPublishing,
|
||||
required this.errorMessage,
|
||||
required this.dietData,
|
||||
final List<List<DailySchedule>>? copiedDay,
|
||||
@@ -296,17 +322,20 @@ class _$CreateDietStateImpl implements _CreateDietState {
|
||||
this.dietDurationError,
|
||||
this.dietStateError,
|
||||
this.dietImageError,
|
||||
required final List<List<String>> dailyScheduleErrors,
|
||||
required final List<String> dailyScheduleErrors,
|
||||
this.durationIndex,
|
||||
this.dietStateIndex,
|
||||
this.published = false,
|
||||
this.drafted = false})
|
||||
this.drafted = false,
|
||||
this.isDietBeingEdited = false})
|
||||
: _copiedDay = copiedDay,
|
||||
_dailyScheduleErrors = dailyScheduleErrors;
|
||||
|
||||
@override
|
||||
final bool isLoading;
|
||||
@override
|
||||
final bool isDietPublishing;
|
||||
@override
|
||||
final String? errorMessage;
|
||||
@override
|
||||
final CreateDietModel dietData;
|
||||
@@ -330,9 +359,9 @@ class _$CreateDietStateImpl implements _CreateDietState {
|
||||
final String? dietStateError;
|
||||
@override
|
||||
final String? dietImageError;
|
||||
final List<List<String>> _dailyScheduleErrors;
|
||||
final List<String> _dailyScheduleErrors;
|
||||
@override
|
||||
List<List<String>> get dailyScheduleErrors {
|
||||
List<String> get dailyScheduleErrors {
|
||||
if (_dailyScheduleErrors is EqualUnmodifiableListView)
|
||||
return _dailyScheduleErrors;
|
||||
// ignore: implicit_dynamic_type
|
||||
@@ -349,10 +378,13 @@ class _$CreateDietStateImpl implements _CreateDietState {
|
||||
@override
|
||||
@JsonKey()
|
||||
final bool drafted;
|
||||
@override
|
||||
@JsonKey()
|
||||
final bool isDietBeingEdited;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'CreateDietState(isLoading: $isLoading, errorMessage: $errorMessage, dietData: $dietData, copiedDay: $copiedDay, dietNameError: $dietNameError, dietDescriptionError: $dietDescriptionError, dietDurationError: $dietDurationError, dietStateError: $dietStateError, dietImageError: $dietImageError, dailyScheduleErrors: $dailyScheduleErrors, durationIndex: $durationIndex, dietStateIndex: $dietStateIndex, published: $published, drafted: $drafted)';
|
||||
return 'CreateDietState(isLoading: $isLoading, isDietPublishing: $isDietPublishing, errorMessage: $errorMessage, dietData: $dietData, copiedDay: $copiedDay, dietNameError: $dietNameError, dietDescriptionError: $dietDescriptionError, dietDurationError: $dietDurationError, dietStateError: $dietStateError, dietImageError: $dietImageError, dailyScheduleErrors: $dailyScheduleErrors, durationIndex: $durationIndex, dietStateIndex: $dietStateIndex, published: $published, drafted: $drafted, isDietBeingEdited: $isDietBeingEdited)';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -362,6 +394,8 @@ class _$CreateDietStateImpl implements _CreateDietState {
|
||||
other is _$CreateDietStateImpl &&
|
||||
(identical(other.isLoading, isLoading) ||
|
||||
other.isLoading == isLoading) &&
|
||||
(identical(other.isDietPublishing, isDietPublishing) ||
|
||||
other.isDietPublishing == isDietPublishing) &&
|
||||
(identical(other.errorMessage, errorMessage) ||
|
||||
other.errorMessage == errorMessage) &&
|
||||
(identical(other.dietData, dietData) ||
|
||||
@@ -386,13 +420,16 @@ class _$CreateDietStateImpl implements _CreateDietState {
|
||||
other.dietStateIndex == dietStateIndex) &&
|
||||
(identical(other.published, published) ||
|
||||
other.published == published) &&
|
||||
(identical(other.drafted, drafted) || other.drafted == drafted));
|
||||
(identical(other.drafted, drafted) || other.drafted == drafted) &&
|
||||
(identical(other.isDietBeingEdited, isDietBeingEdited) ||
|
||||
other.isDietBeingEdited == isDietBeingEdited));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(
|
||||
runtimeType,
|
||||
isLoading,
|
||||
isDietPublishing,
|
||||
errorMessage,
|
||||
dietData,
|
||||
const DeepCollectionEquality().hash(_copiedDay),
|
||||
@@ -405,7 +442,8 @@ class _$CreateDietStateImpl implements _CreateDietState {
|
||||
durationIndex,
|
||||
dietStateIndex,
|
||||
published,
|
||||
drafted);
|
||||
drafted,
|
||||
isDietBeingEdited);
|
||||
|
||||
/// Create a copy of CreateDietState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@@ -420,6 +458,7 @@ class _$CreateDietStateImpl implements _CreateDietState {
|
||||
abstract class _CreateDietState implements CreateDietState {
|
||||
const factory _CreateDietState(
|
||||
{required final bool isLoading,
|
||||
required final bool isDietPublishing,
|
||||
required final String? errorMessage,
|
||||
required final CreateDietModel dietData,
|
||||
final List<List<DailySchedule>>? copiedDay,
|
||||
@@ -428,15 +467,18 @@ abstract class _CreateDietState implements CreateDietState {
|
||||
final String? dietDurationError,
|
||||
final String? dietStateError,
|
||||
final String? dietImageError,
|
||||
required final List<List<String>> dailyScheduleErrors,
|
||||
required final List<String> dailyScheduleErrors,
|
||||
final int? durationIndex,
|
||||
final int? dietStateIndex,
|
||||
final bool published,
|
||||
final bool drafted}) = _$CreateDietStateImpl;
|
||||
final bool drafted,
|
||||
final bool isDietBeingEdited}) = _$CreateDietStateImpl;
|
||||
|
||||
@override
|
||||
bool get isLoading;
|
||||
@override
|
||||
bool get isDietPublishing;
|
||||
@override
|
||||
String? get errorMessage;
|
||||
@override
|
||||
CreateDietModel get dietData;
|
||||
@@ -453,7 +495,7 @@ abstract class _CreateDietState implements CreateDietState {
|
||||
@override
|
||||
String? get dietImageError;
|
||||
@override
|
||||
List<List<String>> get dailyScheduleErrors;
|
||||
List<String> get dailyScheduleErrors;
|
||||
@override
|
||||
int? get durationIndex;
|
||||
@override
|
||||
@@ -462,6 +504,8 @@ abstract class _CreateDietState implements CreateDietState {
|
||||
bool get published;
|
||||
@override
|
||||
bool get drafted;
|
||||
@override
|
||||
bool get isDietBeingEdited;
|
||||
|
||||
/// Create a copy of CreateDietState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
|
||||
@@ -335,7 +335,7 @@ class _DietPreviewScreenState extends State<DietPreviewScreen> {
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
shrinkWrap: true,
|
||||
itemBuilder: (context, index) {
|
||||
return _dayOfPlan(widget.diet.dailySchedule[index], index, s);
|
||||
return _dayOfPlan(widget.diet.dailySchedule[index] ?? {}, index, s);
|
||||
},
|
||||
itemCount: widget.diet.dailySchedule.length,
|
||||
),
|
||||
@@ -363,7 +363,7 @@ class _DietPreviewScreenState extends State<DietPreviewScreen> {
|
||||
);
|
||||
}
|
||||
|
||||
_dayOfPlan(List<List<DailySchedule>> day, int dayNumber, S s) {
|
||||
_dayOfPlan(Map<int, Map<int, DailySchedule>> day, int dayNumber, S s) {
|
||||
_choiceChipWidget(int index) {
|
||||
return ChoiceChip(
|
||||
selectedColor: appTheme.blueA400,
|
||||
@@ -431,8 +431,8 @@ class _DietPreviewScreenState extends State<DietPreviewScreen> {
|
||||
ListView.builder(
|
||||
shrinkWrap: true,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
itemBuilder: (context, index) => _daily(day[widget.selectedIndexes[dayNumber]][index], s),
|
||||
itemCount: day[widget.selectedIndexes[dayNumber]].length,
|
||||
itemBuilder: (context, index) => _daily(day[widget.selectedIndexes[dayNumber] + 1]?[index + 1], s),
|
||||
itemCount: day[widget.selectedIndexes[dayNumber] + 1]?.length ?? 0,
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
],
|
||||
@@ -450,7 +450,8 @@ class _DietPreviewScreenState extends State<DietPreviewScreen> {
|
||||
);
|
||||
}
|
||||
|
||||
_daily(DailySchedule daily, S s) {
|
||||
_daily(DailySchedule? daily, S s) {
|
||||
if (daily == null) return SizedBox.shrink();
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 12),
|
||||
child: Row(
|
||||
|
||||
@@ -199,8 +199,7 @@ class _AddMealWidgetState extends State<AddMealWidget> {
|
||||
final portion = DailySchedule(
|
||||
dailyNutrition: DailyNutrition(energy: calories, proteins: proteins, fats: fats, carbohydrates: carbohydrates),
|
||||
quantity: int.parse(quantityController.text),
|
||||
name: glossary.name,
|
||||
uniq: '',
|
||||
name: glossary.name,
|
||||
productNutritionalValueId: glossary.id.toString(),
|
||||
portion: measurementUnits,
|
||||
);
|
||||
@@ -240,7 +239,6 @@ class _AddMealWidgetState extends State<AddMealWidget> {
|
||||
dailyNutrition: DailyNutrition(energy: calories, proteins: proteins, fats: fats, carbohydrates: carbohydrates),
|
||||
quantity: int.parse(quantityController.text),
|
||||
name: newGlossary.name,
|
||||
uniq: '',
|
||||
productNutritionalValueId: newGlossary.id.toString(),
|
||||
portion: measurementUnits,
|
||||
);
|
||||
|
||||
@@ -35,7 +35,7 @@ class _DayWidgetState extends State<DayWidget> {
|
||||
return BlocBuilder<CreateDietCubit, CreateDietState>(
|
||||
builder: (context, state) {
|
||||
return MainBackgroundBouble(
|
||||
hasError: state.dailyScheduleErrors[widget.index].where((element) => element.isNotEmpty).isNotEmpty,
|
||||
hasError: state.dailyScheduleErrors[widget.index].isNotEmpty,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@@ -216,16 +216,15 @@ class _DayWidgetState extends State<DayWidget> {
|
||||
),
|
||||
],
|
||||
),
|
||||
if (state.dailyScheduleErrors[widget.index][_selectedMealIndex].isNotEmpty) ...[
|
||||
if (state.dailyScheduleErrors[widget.index].isNotEmpty) ...[
|
||||
SizedBox(height: 12),
|
||||
CustomErrorWidget(error: state.dailyScheduleErrors[widget.index][_selectedMealIndex]),
|
||||
CustomErrorWidget(error: state.dailyScheduleErrors[widget.index]),
|
||||
],
|
||||
SizedBox(height: 20),
|
||||
],
|
||||
),
|
||||
),
|
||||
BlocBuilder<CreateDietCubit, CreateDietState>(
|
||||
buildWhen: (previous, current) => previous.dietData.dailySchedule != current.dietData.dailySchedule,
|
||||
builder: (context, state) {
|
||||
if (state.dietData.dailySchedule != null) {
|
||||
final day = state.dietData.dailySchedule?[widget.index];
|
||||
|
||||
@@ -71,6 +71,8 @@ class _DietImagePickerWidgetState extends State<DietImagePickerWidget> {
|
||||
final s = S.of(context);
|
||||
return BlocBuilder<CreateDietCubit, CreateDietState>(
|
||||
builder: (context, state) {
|
||||
final hasImage = state.dietData.image != null || state.dietData.imageUrl != null;
|
||||
final hasFile = state.dietData.image != null;
|
||||
return Column(
|
||||
children: [
|
||||
GestureDetector(
|
||||
@@ -81,17 +83,26 @@ class _DietImagePickerWidgetState extends State<DietImagePickerWidget> {
|
||||
height: 240,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
image: state.dietData.image != null ? DecorationImage(fit: BoxFit.cover, image: FileImage(File(state.dietData.image?.path ?? ''))) : null,
|
||||
image: hasImage
|
||||
? DecorationImage(
|
||||
fit: BoxFit.cover,
|
||||
image: (hasFile
|
||||
? FileImage(
|
||||
File(state.dietData.image?.path ?? ''),
|
||||
)
|
||||
: NetworkImage(state.dietData.imageUrl ?? '')) as ImageProvider,
|
||||
)
|
||||
: null,
|
||||
color: appTheme.gray50,
|
||||
),
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
padding: state.dietData.image != null ? null : EdgeInsets.all(8),
|
||||
child: state.dietData.image != null
|
||||
padding: hasImage ? null : EdgeInsets.all(8),
|
||||
child: hasImage
|
||||
? Padding(
|
||||
padding: const EdgeInsets.only(top: 6, right: 6),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
context.read<CreateDietCubit>().setImage(null);
|
||||
context.read<CreateDietCubit>().setImage(null, imageUrl: null);
|
||||
},
|
||||
child: Align(
|
||||
alignment: Alignment.topRight,
|
||||
|
||||
@@ -18,8 +18,7 @@ class DietTypeChoiceWidget extends StatefulWidget {
|
||||
class _DietTypeChoiceWidgetState extends State<DietTypeChoiceWidget> {
|
||||
final List<(String, String)> choiceContent = [];
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
// const List<String> typeValues = ['veg', 'light', 'carb', 'meat'];
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
final s = S.of(context);
|
||||
if (choiceContent.isEmpty) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_c
|
||||
import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_state.dart';
|
||||
import 'package:eatvio_app/core/widgets/custom_drop_down_button.dart';
|
||||
import 'package:eatvio_app/features/create_diet/presentation/widgets/error_widget.dart';
|
||||
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
|
||||
import 'package:eatvio_app/generated/l10n.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
@@ -18,14 +19,23 @@ class StatusDropDownWidget extends StatefulWidget {
|
||||
|
||||
class _StatusDropDownWidgetState extends State<StatusDropDownWidget> {
|
||||
final List<String> dietStateTitles = [];
|
||||
late final List<DietState> dietStates = DietState.values;
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
final s = S.of(context);
|
||||
if (dietStateTitles.isEmpty) {
|
||||
dietStateTitles.add(s.active_diet_state);
|
||||
dietStateTitles.add(s.personal_diet_state);
|
||||
dietStates.forEach((elem) {
|
||||
switch (elem) {
|
||||
case DietState.active:
|
||||
dietStateTitles.add(s.active_diet_state);
|
||||
case DietState.draft:
|
||||
dietStateTitles.add(s.draft);
|
||||
case DietState.personal:
|
||||
dietStateTitles.add(s.personal_diet_state);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +55,8 @@ class _StatusDropDownWidgetState extends State<StatusDropDownWidget> {
|
||||
),
|
||||
onChanged: (value) {
|
||||
if (value != null) {
|
||||
context.read<CreateDietCubit>().setDietState(dietStateTitles.indexOf(value));
|
||||
final index = dietStates.indexOf(value);
|
||||
context.read<CreateDietCubit>().setDietState(value, index);
|
||||
}
|
||||
},
|
||||
items: dietStateTitles
|
||||
@@ -55,11 +66,11 @@ class _StatusDropDownWidgetState extends State<StatusDropDownWidget> {
|
||||
dietStateTitles[index],
|
||||
style: TextStyles.textMMedium.copyWith(color: appTheme.black),
|
||||
),
|
||||
value: dietStateTitles[index],
|
||||
value: dietStates[index],
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
value: state.dietStateIndex == null ? null : dietStateTitles[state.dietStateIndex ?? 0],
|
||||
value: state.dietStateIndex == null ? null : dietStates[state.dietStateIndex ?? 0],
|
||||
),
|
||||
if (state.dietStateError != null) ...[
|
||||
SizedBox(
|
||||
|
||||
Reference in New Issue
Block a user