added plan pagination and updated plans creation screen

This commit is contained in:
Username1548
2024-12-04 22:03:31 +07:00
parent 4a57c72297
commit bc0b3829c9
50 changed files with 1504 additions and 959 deletions

View File

@@ -0,0 +1,3 @@
<svg width="13" height="13" viewBox="0 0 13 13" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.8" d="M6.39817 10.4C6.62161 10.4 6.81111 10.3228 6.96667 10.1685C7.12222 10.0143 7.2 9.82539 7.2 9.60183C7.2 9.37839 7.12283 9.18889 6.9685 9.03333C6.81428 8.87778 6.62539 8.8 6.40183 8.8C6.17839 8.8 5.98889 8.87717 5.83333 9.0315C5.67778 9.18572 5.6 9.37461 5.6 9.59817C5.6 9.82161 5.67717 10.0111 5.8315 10.1667C5.98572 10.3222 6.17461 10.4 6.39817 10.4ZM6.40467 12.8C5.52378 12.8 4.69444 12.6333 3.91667 12.3C3.13889 11.9667 2.45833 11.5083 1.875 10.925C1.29167 10.3417 0.833333 9.66133 0.5 8.884C0.166667 8.10667 0 7.27611 0 6.39233C0 5.50856 0.166667 4.68056 0.5 3.90833C0.833333 3.13611 1.29167 2.45833 1.875 1.875C2.45833 1.29167 3.13867 0.833333 3.916 0.5C4.69333 0.166667 5.52389 0 6.40767 0C7.29144 0 8.11944 0.166667 8.89167 0.5C9.66389 0.833333 10.3417 1.29167 10.925 1.875C11.5083 2.45833 11.9667 3.13733 12.3 3.912C12.6333 4.68678 12.8 5.51456 12.8 6.39533C12.8 7.27622 12.6333 8.10555 12.3 8.88333C11.9667 9.66111 11.5083 10.3417 10.925 10.925C10.3417 11.5083 9.66267 11.9667 8.888 12.3C8.11322 12.6333 7.28544 12.8 6.40467 12.8ZM6.4 11.6C7.84444 11.6 9.07222 11.0944 10.0833 10.0833C11.0944 9.07222 11.6 7.84444 11.6 6.4C11.6 4.95556 11.0944 3.72778 10.0833 2.71667C9.07222 1.70556 7.84444 1.2 6.4 1.2C4.95556 1.2 3.72778 1.70556 2.71667 2.71667C1.70556 3.72778 1.2 4.95556 1.2 6.4C1.2 7.84444 1.70556 9.07222 2.71667 10.0833C3.72778 11.0944 4.95556 11.6 6.4 11.6ZM6.45383 3.53333C6.73506 3.53333 6.97972 3.62339 7.18783 3.8035C7.39594 3.9835 7.5 4.20855 7.5 4.47867C7.5 4.72622 7.42778 4.94444 7.28333 5.13333C7.13889 5.32222 6.97222 5.49444 6.78333 5.65C6.52778 5.87222 6.3 6.12222 6.1 6.4C5.9 6.67778 5.80556 6.98889 5.81667 7.33333C5.81667 7.48889 5.87267 7.61389 5.98467 7.70833C6.09667 7.80278 6.22733 7.85 6.37667 7.85C6.53667 7.85 6.67222 7.80278 6.78333 7.70833C6.89444 7.61389 6.96667 7.48889 7 7.33333C7.05556 7.08889 7.16111 6.87311 7.31667 6.686C7.47222 6.49878 7.63889 6.32011 7.81667 6.15C8.07222 5.90556 8.28055 5.63333 8.44167 5.33333C8.60278 5.03333 8.68333 4.71111 8.68333 4.36667C8.68333 3.8 8.46389 3.33056 8.025 2.95833C7.58611 2.58611 7.06439 2.4 6.45983 2.4C6.04217 2.4 5.64722 2.49167 5.275 2.675C4.90278 2.85833 4.60467 3.12928 4.38067 3.48783C4.29356 3.61817 4.26944 3.76111 4.30833 3.91667C4.34722 4.07222 4.43889 4.18333 4.58333 4.25C4.73889 4.32778 4.89444 4.34444 5.05 4.3C5.20556 4.25556 5.33333 4.17222 5.43333 4.05C5.55556 3.89444 5.70556 3.76944 5.88333 3.675C6.06111 3.58056 6.25128 3.53333 6.45383 3.53333Z" fill="#323F4B"/>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -0,0 +1,6 @@
<svg width="22" height="24" viewBox="0 0 22 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7.49914 0.0902882C6.87114 0.315243 6.38842 0.802647 6.16815 1.44002C6.09785 1.63686 6.0791 1.82901 6.0791 2.25548V2.8085H4.12012C2.29704 2.8085 2.1377 2.81318 1.894 2.89754C1.40659 3.06626 1.00823 3.38963 0.717667 3.8536C0.333368 4.47223 0.370861 5.48453 0.806712 6.12659C0.998862 6.40779 1.42065 6.75928 1.69716 6.86707L1.88462 6.93737L2.51262 14.4968C2.85474 18.6585 3.15468 22.164 3.17812 22.2859C3.31403 23.0311 3.9186 23.6965 4.66845 23.9262C4.99182 24.0246 17.0082 24.0246 17.3316 23.9262C17.6737 23.8231 17.9033 23.6872 18.1892 23.4294C18.4798 23.1576 18.7516 22.6749 18.8219 22.2906C18.8453 22.164 19.1453 18.6585 19.4874 14.5015L20.1154 6.93737L20.3028 6.86707C20.5794 6.75928 21.0011 6.40779 21.1933 6.12659C21.6291 5.48453 21.6666 4.47223 21.2823 3.8536C20.9918 3.38963 20.5934 3.06626 20.106 2.89754C19.8623 2.81318 19.703 2.8085 17.8799 2.8085H15.9209V2.25548C15.9209 1.82901 15.9022 1.63686 15.8319 1.44002C15.6116 0.793274 15.1242 0.30587 14.4821 0.0856018C14.2291 0.00124359 14.0697 -0.00344276 10.9813 0.00124359C7.94905 0.00124359 7.72878 0.0106163 7.49914 0.0902882ZM14.1306 1.51969C14.3931 1.67904 14.4774 1.87119 14.5056 2.36796L14.529 2.8085H11H7.47102L7.49445 2.36796C7.52726 1.77277 7.66785 1.54313 8.0709 1.44471C8.15057 1.42596 9.50967 1.4119 11.0937 1.41659C13.8869 1.42596 13.9807 1.43065 14.1306 1.51969ZM19.7639 4.34101C19.9795 4.47223 20.092 4.67375 20.092 4.91746C20.092 5.16116 19.9795 5.36268 19.7639 5.4939L19.5999 5.59701H11C2.4845 5.59701 2.40015 5.59701 2.24549 5.50328C1.71122 5.1799 1.83307 4.40662 2.44233 4.25665C2.522 4.2379 6.41654 4.22853 11.0937 4.22853L19.5999 4.2379L19.7639 4.34101ZM18.6391 7.05922C18.6391 7.08265 18.3626 10.4476 18.0252 14.5484C17.5378 20.4534 17.3972 22.0328 17.3362 22.1593C17.2378 22.3609 17.0738 22.4827 16.8301 22.539C16.5864 22.5952 5.41361 22.5952 5.16991 22.539C4.92621 22.4827 4.76218 22.3609 4.66376 22.1593C4.60283 22.0328 4.46224 20.4534 3.97483 14.5484C3.6374 10.4476 3.36089 7.08265 3.36089 7.05922C3.36089 7.04047 6.80084 7.02641 11 7.02641C15.2039 7.02641 18.6391 7.04047 18.6391 7.05922Z" fill="#6D6F71"/>
<path d="M6.38842 8.52135C6.14471 8.6807 6.0791 8.84004 6.0791 9.25246C6.0791 9.45867 6.23844 12.1206 6.42591 15.1669C6.80552 21.2501 6.76334 20.8845 7.0914 21.0907C7.3023 21.2173 7.69128 21.2126 7.88812 21.0767C8.12713 20.9126 8.18806 20.7674 8.18806 20.3503C8.18806 20.1487 8.02872 17.4915 7.84125 14.4405C7.50382 9.00407 7.49445 8.89628 7.38665 8.74162C7.32573 8.65258 7.22262 8.54947 7.15233 8.50729C6.97424 8.3995 6.56182 8.40888 6.38842 8.52135Z" fill="#6D6F71"/>
<path d="M10.6063 8.52138C10.536 8.56825 10.4329 8.67135 10.3861 8.74165C10.3017 8.87288 10.297 9.07908 10.297 14.8061C10.297 20.5331 10.3017 20.7393 10.3861 20.8705C10.5314 21.0861 10.7094 21.1798 11 21.1798C11.2906 21.1798 11.4687 21.0861 11.614 20.8705C11.6983 20.7393 11.703 20.5331 11.703 14.8061C11.703 9.07908 11.6983 8.87288 11.614 8.74165C11.4687 8.52607 11.2906 8.43234 11 8.43234C10.8266 8.43234 10.7001 8.46046 10.6063 8.52138Z" fill="#6D6F71"/>
<path d="M14.8243 8.52148C14.4962 8.73706 14.5384 8.34808 14.1588 14.4453C13.9713 17.4916 13.812 20.1535 13.812 20.3598C13.812 20.7722 13.8776 20.9315 14.1213 21.0909C14.304 21.2127 14.7118 21.2127 14.9086 21.0909C15.2367 20.8847 15.1945 21.2502 15.5741 15.167C15.7616 12.1208 15.9209 9.45879 15.9209 9.25258C15.9209 8.84017 15.8553 8.68082 15.6116 8.52148C15.4241 8.39963 15.007 8.39963 14.8243 8.52148Z" fill="#6D6F71"/>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -23,7 +23,7 @@ import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_cubit
import 'package:eatvio_app/features/feed/presentation/pages/feed_screen.dart';
import 'package:eatvio_app/features/menu/presentation/pages/menu_screen.dart';
import 'package:eatvio_app/features/notifications/presentation/pages/notifications_screen.dart';
import 'package:eatvio_app/features/plans/models/plan_pagination_model.dart';
import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart';
import 'package:eatvio_app/features/plans/presentation/pages/about_plan_screen.dart';
import 'package:eatvio_app/features/profile/presentation/pages/profile_screen.dart';
import 'package:eatvio_app/features/profile/presentation/pages/subs_screen.dart';

View File

@@ -26,7 +26,7 @@ import 'package:eatvio_app/features/consultant/become_consultant/services/consul
import 'package:eatvio_app/features/diary/presentation/bloc/diary_cubit.dart';
import 'package:eatvio_app/features/diary/repositories/diary_repository.dart';
import 'package:eatvio_app/features/diary/services/diary_service.dart';
import 'package:eatvio_app/features/diets/presentation/bloc/about_diet_cubit.dart';
import 'package:eatvio_app/features/diets/presentation/cubit/about_diet_cubit.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/comments_cubit/comments_cubit.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_cubit.dart';
@@ -35,9 +35,7 @@ import 'package:eatvio_app/features/feed/repositories/feed_repository.dart';
import 'package:eatvio_app/features/feed/services/feed_service.dart';
import 'package:eatvio_app/features/glossary/repositories/glossary_repository.dart';
import 'package:eatvio_app/features/glossary/services/glossary_service.dart';
import 'package:eatvio_app/features/plans/presentation/bloc/plans_cubit/plans_cubit.dart';
import 'package:eatvio_app/features/plans/repositories/plans_repository.dart';
import 'package:eatvio_app/features/plans/services/plans_service.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/plans_cubit/plans_cubit.dart';
import 'package:eatvio_app/features/profile/presentation/bloc/profile_cubit/profile_cubit.dart';
import 'package:eatvio_app/features/profile/presentation/bloc/sub_cubit/sub_cubit.dart';
import 'package:eatvio_app/features/profile/repositories/profile_repository.dart';
@@ -73,7 +71,7 @@ Future<void> init() async {
sl.registerFactory<DietsCubit>(() => DietsCubit(feedRepository: sl(), dietsRepository: sl()));
sl.registerFactory<CommentsCubit>(() => CommentsCubit(feedRepository: sl()));
sl.registerFactory<ChatSelectCubit>(() => ChatSelectCubit(chatRepository: sl()));
sl.registerFactory<PlansCubit>(() => PlansCubit(plansRepository: sl()));
sl.registerFactory<PlansCubit>(() => PlansCubit(feedRepository: sl()));
sl.registerFactory<SettingsCubit>(() => SettingsCubit(profileRepository: sl(), settingsRepository: sl()));
sl.registerFactory<RegisterConsultantCubit>(() => RegisterConsultantCubit(consultantRepository: sl()));
sl.registerFactory<DiaryCubit>(() => DiaryCubit(diaryRepository: sl(), glossaryRepository: sl()));
@@ -91,7 +89,6 @@ Future<void> init() async {
sl.registerLazySingleton<CalendarRepository>(() => CalendarRepository(calendarService: sl()));
sl.registerLazySingleton<ProfileRepository>(() => ProfileRepository(profileService: sl()));
sl.registerLazySingleton<RecipeRepository>(() => RecipeRepository(recipeService: sl()));
sl.registerLazySingleton<PlansRepository>(() => PlansRepository(plansService: sl()));
sl.registerLazySingleton<SettingsRepository>(() => SettingsRepository(settingsService: sl()));
sl.registerLazySingleton<ConsultantRepository>(() => ConsultantRepository(consultantService: sl()));
sl.registerLazySingleton<DiaryRepository>(() => DiaryRepository(diaryService: sl()));
@@ -107,7 +104,6 @@ Future<void> init() async {
sl.registerLazySingleton<CalendarService>(() => CalendarService(sl()));
sl.registerLazySingleton<ProfileService>(() => ProfileService(sl()));
sl.registerLazySingleton<RecipeService>(() => RecipeService(sl()));
sl.registerLazySingleton<PlansService>(() => PlansService(sl()));
sl.registerLazySingleton<SettingsService>(() => SettingsService(sl()));
sl.registerLazySingleton<ConsultantService>(() => ConsultantService(sl()));
sl.registerLazySingleton<DiaryService>(() => DiaryService(sl()));

View File

@@ -79,6 +79,7 @@ class CustomTextFormField extends StatelessWidget {
return Align(
alignment: alignment ?? Alignment.center,
child: TextFormField(
textAlignVertical: textAlignVertical,
expands: expands,
minLines: minLines,

View File

@@ -1,7 +1,3 @@
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:eatvio_app/core/image_compressing/image_compress_utility.dart';
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
import 'package:flutter_image_compress/flutter_image_compress.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
@@ -17,21 +13,8 @@ class CreateDietModel with _$CreateDietModel {
String? details,
String? state,
int? duration,
required List<bool> type,
required Map<String, bool> type,
XFile? image,
List<List<List<DailySchedule>>>? dailySchedule,
}) = _CreateDietModel;
Future<Map<String, dynamic>> toCreationJson() async => {
'name': name,
'duration': duration,
'state': state,
'type': type,
'details': details,
'image': image != null ? await MultipartFile.fromFile((await ImageCompressUtility.compressFile(File(image!.path))).path, filename: image!.name) : null,
};
Map<String, dynamic> toDailyScheduleCreationJson() => {
'daily_schedule': dailySchedule?.map((element) => element.map((element) => element.map((element) => element.toJson()).toList()).toList()).toList(),
};
}

View File

@@ -20,7 +20,7 @@ mixin _$CreateDietModel {
String? get details => throw _privateConstructorUsedError;
String? get state => throw _privateConstructorUsedError;
int? get duration => throw _privateConstructorUsedError;
List<bool> get type => throw _privateConstructorUsedError;
Map<String, bool> get type => throw _privateConstructorUsedError;
XFile? get image => throw _privateConstructorUsedError;
List<List<List<DailySchedule>>>? get dailySchedule =>
throw _privateConstructorUsedError;
@@ -43,7 +43,7 @@ abstract class $CreateDietModelCopyWith<$Res> {
String? details,
String? state,
int? duration,
List<bool> type,
Map<String, bool> type,
XFile? image,
List<List<List<DailySchedule>>>? dailySchedule});
}
@@ -91,7 +91,7 @@ class _$CreateDietModelCopyWithImpl<$Res, $Val extends CreateDietModel>
type: null == type
? _value.type
: type // ignore: cast_nullable_to_non_nullable
as List<bool>,
as Map<String, bool>,
image: freezed == image
? _value.image
: image // ignore: cast_nullable_to_non_nullable
@@ -117,7 +117,7 @@ abstract class _$$CreateDietModelImplCopyWith<$Res>
String? details,
String? state,
int? duration,
List<bool> type,
Map<String, bool> type,
XFile? image,
List<List<List<DailySchedule>>>? dailySchedule});
}
@@ -163,7 +163,7 @@ class __$$CreateDietModelImplCopyWithImpl<$Res>
type: null == type
? _value._type
: type // ignore: cast_nullable_to_non_nullable
as List<bool>,
as Map<String, bool>,
image: freezed == image
? _value.image
: image // ignore: cast_nullable_to_non_nullable
@@ -184,7 +184,7 @@ class _$CreateDietModelImpl extends _CreateDietModel {
this.details,
this.state,
this.duration,
required final List<bool> type,
required final Map<String, bool> type,
this.image,
final List<List<List<DailySchedule>>>? dailySchedule})
: _type = type,
@@ -199,12 +199,12 @@ class _$CreateDietModelImpl extends _CreateDietModel {
final String? state;
@override
final int? duration;
final List<bool> _type;
final Map<String, bool> _type;
@override
List<bool> get type {
if (_type is EqualUnmodifiableListView) return _type;
Map<String, bool> get type {
if (_type is EqualUnmodifiableMapView) return _type;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_type);
return EqualUnmodifiableMapView(_type);
}
@override
@@ -267,7 +267,7 @@ abstract class _CreateDietModel extends CreateDietModel {
final String? details,
final String? state,
final int? duration,
required final List<bool> type,
required final Map<String, bool> type,
final XFile? image,
final List<List<List<DailySchedule>>>? dailySchedule}) =
_$CreateDietModelImpl;
@@ -282,7 +282,7 @@ abstract class _CreateDietModel extends CreateDietModel {
@override
int? get duration;
@override
List<bool> get type;
Map<String, bool> get type;
@override
XFile? get image;
@override

View File

@@ -1,5 +1,9 @@
import 'dart:convert';
import 'dart:io';
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/core/locator_service.dart';
import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_state.dart';
import 'package:eatvio_app/features/create_diet/repositories/create_diet_repository.dart';
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
@@ -89,7 +93,9 @@ class CreateDietCubit extends Cubit<CreateDietState> {
emit(state.copyWith(dietStateIndex: index, dietData: state.dietData.copyWith(state: _dietStateValues[index])));
}
void setDietType(List<bool> type) {
void setDietType({required String key, required bool value}) {
final type = Map<String, bool>.from(state.dietData.type);
type[key] = value;
emit(state.copyWith(dietData: state.dietData.copyWith(type: type)));
}
@@ -248,19 +254,24 @@ class CreateDietCubit extends Cubit<CreateDietState> {
}
Future<void> publishDiet() async {
// бек судя по всему с багом
// try {
// final model = await state.dietData.toCreationJson();
// model.remove('image');
// final dailySchedule = await state.dietData.toDailyScheduleCreationJson();
// final dio = sl<Dio>();
// final qwe = await dio.post('/api/diets/create', data: model);
// // final diet = await createDietRepository.createDiet(model: model);
// // final qwe2 = createDietRepository.createDietDailySchedule(id: diet.id, model: dailySchedule);
// } catch (e, stackTrace) {
// print(e);
// print('---------------------------------');
// print(stackTrace);
// }
try {
// final types = jsonEncode(state.dietData.type);
// if (state.dietData.image == null) {
// return;
// }
// final image = await ImageCompressUtility.compressFile(File(state.dietData.image!.path));
// final diet = await createDietRepository.createDiet(
// name: state.dietData.name,
// duration: state.dietData.duration,
// state: state.dietData.state,
// image: image,
// type: types,
// details: state.dietData.details,
// );
} catch (e, stackTrace) {
print(e);
print('---------------------------------');
print(stackTrace);
}
}
}

View File

@@ -1,3 +1,4 @@
import 'package:eatvio_app/core/const.dart';
import 'package:eatvio_app/features/create_diet/models/create_diet_model.dart';
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
@@ -6,14 +7,20 @@ part 'create_diet_state.freezed.dart';
@freezed
class CreateDietState with _$CreateDietState {
const factory CreateDietState({
const factory CreateDietState({
required bool isLoading,
required String? errorMessage,
required CreateDietModel dietData,
List<List<DailySchedule>>? copiedDay,
required CreateDietModel dietData,
List<List<DailySchedule>>? copiedDay,
int? durationIndex,
int? dietStateIndex,
}) = _CreateDietState;
factory CreateDietState.initial() => CreateDietState(isLoading: false, errorMessage: null, dietData: CreateDietModel(type: [false, false, false, false]));
factory CreateDietState.initial() => CreateDietState(
isLoading: false,
errorMessage: null,
dietData: CreateDietModel(
type: Map.fromIterable(typeValues, value: (element) => false),
),
);
}

View File

@@ -1,3 +1,4 @@
import 'package:eatvio_app/core/const.dart';
import 'package:eatvio_app/core/theme/custom_text_style.dart';
import 'package:eatvio_app/core/theme/theme_helper.dart';
import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_cubit.dart';
@@ -18,15 +19,11 @@ class _DietTypeChoiceWidgetState extends State<DietTypeChoiceWidget> {
final List<(String, String)> choiceContent = [];
@override
void didChangeDependencies() {
// const List<String> typeValues = ['veg', 'light', 'carb', 'meat'];
super.didChangeDependencies();
final s = S.of(context);
if (choiceContent.isEmpty) {
choiceContent.add(
(
'assets/icons/meat2.svg',
s.meat,
),
);
choiceContent.add(
(
'assets/icons/broccoli.svg',
@@ -35,14 +32,20 @@ class _DietTypeChoiceWidgetState extends State<DietTypeChoiceWidget> {
);
choiceContent.add(
(
'assets/icons/bread.svg',
s.carb_type,
'assets/icons/cocktail.svg',
s.light_type,
),
);
choiceContent.add(
(
'assets/icons/cocktail.svg',
s.light_type,
'assets/icons/bread.svg',
s.carb_type,
),
);
choiceContent.add(
(
'assets/icons/meat2.svg',
s.meat,
),
);
}
@@ -58,18 +61,18 @@ class _DietTypeChoiceWidgetState extends State<DietTypeChoiceWidget> {
return Expanded(
child: GestureDetector(
onTap: () {
final dietTypes = [...state.dietData.type];
dietTypes[index] = !dietTypes[index];
context.read<CreateDietCubit>().setDietType(dietTypes);
final key = typeValues[index];
final value = !(state.dietData.type[key] ?? true);
context.read<CreateDietCubit>().setDietType(key: key, value: value);
},
child: Container(
margin: EdgeInsets.only(right: index == 3 ? 0 : 4),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: state.dietData.type[index] ? appTheme.cardBackground : appTheme.whiteA700,
color: state.dietData.type[typeValues[index]] == true ? appTheme.cardBackground : appTheme.whiteA700,
border: Border.all(
width: 1,
color: state.dietData.type[index] ? appTheme.blueA400 : appTheme.lightGray00,
color: state.dietData.type[typeValues[index]] == true ? appTheme.blueA400 : appTheme.lightGray00,
),
),
height: 80,

View File

@@ -1,3 +1,5 @@
import 'dart:io';
import 'package:eatvio_app/features/create_diet/services/create_diet_service.dart';
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
@@ -6,10 +8,20 @@ class CreateDietRepository {
CreateDietRepository({required this.createDietService});
Future<Diet> createDiet({
required Map<String, dynamic> model,
String? name,
int? duration,
String? state,
String? type,
String? details,
File? image,
}) {
return createDietService.createDiet(
model: model,
name: name,
duration: duration,
state: state,
type: type,
details: details,
image: image,
);
}

View File

@@ -1,3 +1,5 @@
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
import 'package:retrofit/retrofit.dart';
@@ -11,7 +13,12 @@ abstract class CreateDietService {
@POST('/api/diets/create')
@MultiPart()
Future<Diet> createDiet({
@Body() required Map<String, dynamic> model,
@Part(name: 'name') String? name,
@Part(name: 'duration') int? duration,
@Part(name: 'state') String? state,
@Part(name: 'type') String? type,
@Part(name: 'details') String? details,
@Part(name: 'image') File? image,
});
@POST('/api/diets/create/{id}/daily_schedule')

View File

@@ -22,12 +22,60 @@ class _CreateDietService implements CreateDietService {
final ParseErrorLogger? errorLogger;
@override
Future<Diet> createDiet({required Map<String, dynamic> model}) async {
Future<Diet> createDiet({
String? name,
int? duration,
String? state,
String? type,
String? details,
File? image,
}) async {
final _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
queryParameters.removeWhere((k, v) => v == null);
final _headers = <String, dynamic>{};
final _data = <String, dynamic>{};
_data.addAll(model);
final _data = FormData();
if (name != null) {
_data.fields.add(MapEntry(
'name',
name,
));
}
if (duration != null) {
_data.fields.add(MapEntry(
'duration',
duration.toString(),
));
}
if (state != null) {
_data.fields.add(MapEntry(
'state',
state,
));
}
if (type != null) {
_data.fields.add(MapEntry(
'type',
type,
));
}
if (details != null) {
_data.fields.add(MapEntry(
'details',
details,
));
}
if (image != null) {
if (image != null) {
_data.files.add(MapEntry(
'image',
MultipartFile.fromFileSync(
image.path,
filename: image.path.split(Platform.pathSeparator).last,
),
));
}
}
final _options = _setStreamType<Diet>(Options(
method: 'POST',
headers: _headers,

View File

@@ -2,7 +2,7 @@ import 'dart:io';
import 'package:dio/dio.dart';
import 'package:eatvio_app/core/image_compressing/image_compress_utility.dart';
import 'package:eatvio_app/features/plans/models/plan_pagination_model.dart';
import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart';
import 'package:flutter_image_compress/flutter_image_compress.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
@@ -16,7 +16,7 @@ class CreatePlanModel with _$CreatePlanModel {
String? name,
String? details,
String? state,
int? duration,
int? duration,
required List<bool> type,
XFile? image,
required List<PacketOptions> options,

View File

@@ -1,9 +1,12 @@
import 'package:eatvio_app/core/locator_service.dart';
import 'package:eatvio_app/core/theme/custom_text_style.dart';
import 'package:eatvio_app/core/theme/theme_helper.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/main_background_bouble.dart';
import 'package:eatvio_app/features/create_plan/presentation/cubit/create_plan_cubit.dart';
import 'package:eatvio_app/features/create_plan/presentation/cubit/create_plan_state.dart';
import 'package:eatvio_app/features/create_plan/presentation/widgets/option_widget.dart';
import 'package:eatvio_app/features/create_plan/presentation/widgets/options_count_button.dart';
import 'package:eatvio_app/features/create_plan/presentation/widgets/plan_duration_drop_down_widget.dart';
import 'package:eatvio_app/features/create_plan/presentation/widgets/plan_image_picker_widget.dart';
@@ -118,7 +121,7 @@ class CreatePlanScreenContent extends StatelessWidget {
Padding(
padding: const EdgeInsets.only(left: 16),
child: Text(
s.plan_desc,
s.services,
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
softWrap: true,
@@ -127,16 +130,80 @@ class CreatePlanScreenContent extends StatelessWidget {
),
SizedBox(height: 8),
OptionsCountButton(),
SizedBox(height: 200),
SizedBox(height: 20),
BlocBuilder<CreatePlanCubit, CreatePlanState>(
buildWhen: (previous, current) => previous.selectedOptionIndex != current.selectedOptionIndex,
builder: (context, state) {
if (state.selectedOptionIndex == null) {
return SizedBox.shrink();
}
return Padding(
padding: const EdgeInsets.only(left: 16),
child: Text(
'${s.option} ${(state.selectedOptionIndex ?? 0) + 1}',
style: TextStyles.textLSemibold.copyWith(color: appTheme.blueGray400),
),
);
},
),
SizedBox(height: 8),
OptionWidget(),
SizedBox(height: 20),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Column(
children: [
CustomOutlinedButton(
onPressed: () {},
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 {},
text: s.preview,
height: 52,
buttonTextStyle: TextStyles.textMSemibold.copyWith(color: appTheme.gray),
buttonStyle: ButtonStyle(
side: WidgetStatePropertyAll(BorderSide.none),
backgroundColor: WidgetStatePropertyAll(appTheme.dottedBorder),
),
),
SizedBox(height: 12),
CustomOutlinedButton(
onPressed: () {},
text: s.publish,
height: 52,
buttonTextStyle: TextStyles.textMSemibold.copyWith(color: appTheme.whiteA700),
buttonStyle: ButtonStyle(
side: WidgetStatePropertyAll(BorderSide.none),
backgroundColor: WidgetStatePropertyAll(appTheme.blueA400),
),
),
],
),
),
],
),
),
Padding(
padding: const EdgeInsets.only(bottom: 24.0),
child: Align(
alignment: Alignment.bottomCenter,
child: SelectExactOptionWidget(),
),
BlocBuilder<CreatePlanCubit, CreatePlanState>(
builder: (context, state) {
if (state.selectedOptionIndex == null) {
return SizedBox.shrink();
}
return Padding(
padding: const EdgeInsets.only(bottom: 24.0),
child: Align(
alignment: Alignment.bottomCenter,
child: SelectExactOptionWidget(),
),
);
},
),
],
),

View File

@@ -14,6 +14,45 @@ class CreatePlanCubit extends Cubit<CreatePlanState> {
emit(state.copyWith(planData: state.planData.copyWith(name: name)));
}
void setOptionTitle(String title) {
final options = [...state.planData.options];
options[state.selectedOptionIndex ?? 0] = options[state.selectedOptionIndex ?? 0].copyWith(short: title);
emit(state.copyWith(planData: state.planData.copyWith(options: options)));
}
void setPrice(double price){
final selectedOptionIndex = state.selectedOptionIndex ?? 0;
final options = [...state.planData.options];
options[selectedOptionIndex] = options[selectedOptionIndex].copyWith(price: price);
emit(state.copyWith(planData: state.planData.copyWith(options: options)));
}
void setOptionDescription(String description) {
final options = [...state.planData.options];
options[state.selectedOptionIndex ?? 0] = options[state.selectedOptionIndex ?? 0].copyWith(description: description);
emit(state.copyWith(planData: state.planData.copyWith(options: options)));
}
void setOptionContent(String content, index) {
final options = [...state.planData.options];
final items = [...options[state.selectedOptionIndex ?? 0].items];
if (items.length <= index) {
items.add(content);
}else {
items[index] = content;
}
options[state.selectedOptionIndex ?? 0] = options[state.selectedOptionIndex ?? 0].copyWith(items: items);
emit(state.copyWith(planData: state.planData.copyWith(options: options)));
}
void removeOptionContentItem(int index) {
final options = [...state.planData.options];
final updatedItems = [...options[state.selectedOptionIndex ?? 0].items];
updatedItems.removeAt(index);
options[state.selectedOptionIndex ?? 0] = options[state.selectedOptionIndex ?? 0].copyWith(items: updatedItems);
emit(state.copyWith(planData: state.planData.copyWith(options: options)));
}
void setDuration(int index) {
emit(
state.copyWith(

View File

@@ -1,5 +1,5 @@
import 'package:eatvio_app/features/create_plan/models/create_plan_model.dart';
import 'package:eatvio_app/features/plans/models/plan_pagination_model.dart';
import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'create_plan_state.freezed.dart';
@@ -9,7 +9,7 @@ class CreatePlanState with _$CreatePlanState {
const factory CreatePlanState({
required bool isLoading,
required String? errorMessage,
required CreatePlanModel planData,
required CreatePlanModel planData,
int? durationIndex,
int? selectedOptionIndex,
}) = _CreatePlanState;
@@ -20,6 +20,6 @@ class CreatePlanState with _$CreatePlanState {
planData: CreatePlanModel(
type: [false, false, false, false],
options: [PacketOptions.empty(), PacketOptions.empty(), PacketOptions.empty()],
),
),
);
}

View File

@@ -0,0 +1,72 @@
import 'package:eatvio_app/core/theme/theme_helper.dart';
import 'package:eatvio_app/core/widgets/custom_text_form_field.dart';
import 'package:eatvio_app/features/create_plan/presentation/cubit/create_plan_cubit.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
class AddItemWidget extends StatefulWidget {
AddItemWidget({
super.key,
required this.canBeDeleted,
required this.enableHint,
required this.index,
required this.items,
});
final int index;
final bool canBeDeleted;
final bool enableHint;
final List<String> items;
@override
State<AddItemWidget> createState() => _AddItemWidgetState();
}
class _AddItemWidgetState extends State<AddItemWidget> {
final controller = TextEditingController();
@override
void didUpdateWidget(oldWidget) {
super.didUpdateWidget(oldWidget);
if (!widget.canBeDeleted && widget.items.length >= widget.index) {
controller.clear();
}
}
@override
Widget build(BuildContext context) {
final s = S.of(context);
if (widget.items.length > widget.index && controller.text != widget.items[widget.index]) {
controller.text = widget.items[widget.index];
}
return Row(
children: [
Expanded(
child: CustomTextFormField(
controller: controller,
hintText: widget.enableHint ? s.option_content_hint_text : null,
onChanged: (value) {
context.read<CreatePlanCubit>().setOptionContent(value, widget.index);
},
),
),
if (widget.canBeDeleted) ...[
SizedBox(width: 8),
GestureDetector(
onTap: () {
context.read<CreatePlanCubit>().removeOptionContentItem(widget.index);
},
child: Container(
padding: EdgeInsets.all(14),
decoration: BoxDecoration(
color: appTheme.lightGray0,
borderRadius: BorderRadius.circular(20),
),
child: SvgPicture.asset('assets/icons/trash_can.svg', width: 20, height: 24),
),
),
],
],
);
}
}

View File

@@ -1,10 +1,320 @@
import 'package:eatvio_app/core/theme/custom_text_style.dart';
import 'package:eatvio_app/core/theme/theme_helper.dart';
import 'package:eatvio_app/core/widgets/custom_divider.dart';
import 'package:eatvio_app/core/widgets/custom_text_form_field.dart';
import 'package:eatvio_app/core/widgets/main_background_bouble.dart';
import 'package:eatvio_app/features/create_plan/presentation/cubit/create_plan_cubit.dart';
import 'package:eatvio_app/features/create_plan/presentation/cubit/create_plan_state.dart';
import 'package:eatvio_app/features/create_plan/presentation/widgets/add_item_widget.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_portal/flutter_portal.dart';
import 'package:flutter_svg/flutter_svg.dart';
class OptionWidget extends StatelessWidget {
const OptionWidget({super.key});
class OptionWidget extends StatefulWidget {
OptionWidget({super.key});
@override
State<OptionWidget> createState() => _OptionWidgetState();
}
class _OptionWidgetState extends State<OptionWidget> {
final customerPriceController = TextEditingController()..text = '1200₽';
final creatorPriceController = TextEditingController()..text = '1000₽';
final optionTitleController = TextEditingController();
final optionDescriptionController = TextEditingController();
bool firstExplanationVisible = false;
bool isChecked = false;
bool secondExplanationVisible = false;
@override
void initState() {
super.initState();
customerPriceController.addListener(() {
if (!customerPriceController.text.endsWith('₽')) {
final textWithoutCurrency = customerPriceController.text.replaceAll('₽', '');
customerPriceController.value = TextEditingValue(
text: "$textWithoutCurrency₽",
selection: TextSelection.collapsed(offset: textWithoutCurrency.length),
);
}
final price = double.tryParse(customerPriceController.text.replaceAll('₽', ''));
if (price != null && price < 1200) {
customerPriceController.value = TextEditingValue(
text: "1200₽",
selection: TextSelection.collapsed(offset: 4),
);
}
});
creatorPriceController.addListener(() {
if (!creatorPriceController.text.endsWith('₽')) {
final textWithoutCurrency = creatorPriceController.text.replaceAll('₽', '');
creatorPriceController.value = TextEditingValue(
text: "$textWithoutCurrency₽",
selection: TextSelection.collapsed(offset: textWithoutCurrency.length),
);
}
final price = double.tryParse(creatorPriceController.text.replaceAll('₽', ''));
if (price != null && price < 1000) {
creatorPriceController.value = TextEditingValue(
text: "1000₽",
selection: TextSelection.collapsed(offset: 4),
);
}
});
}
@override
Widget build(BuildContext context) {
return Placeholder();
final s = S.of(context);
return BlocBuilder<CreatePlanCubit, CreatePlanState>(
builder: (context, state) {
final optionNameHintText = switch (state.selectedOptionIndex ?? 1) {
0 => s.economy,
2 => s.comfort,
_ => s.standard,
};
final selectedOptionIndex = state.selectedOptionIndex ?? 0;
optionTitleController.text = state.planData.options[selectedOptionIndex].short;
optionDescriptionController.text = state.planData.options[selectedOptionIndex].description;
return MainBackgroundBouble(
padding: EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
s.option_title,
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
softWrap: true,
style: TextStyles.textSMedium.copyWith(color: appTheme.black),
),
SizedBox(height: 4),
CustomTextFormField(
hintText: optionNameHintText,
controller: optionTitleController,
onChanged: (value) {
context.read<CreatePlanCubit>().setOptionTitle(value);
},
maxLength: 150,
),
SizedBox(height: 12),
Text(
s.option_desc,
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
softWrap: true,
style: TextStyles.textSMedium.copyWith(color: appTheme.black),
),
SizedBox(height: 4),
SizedBox(
height: 120,
child: CustomTextFormField(
controller: optionDescriptionController,
textAlignVertical: TextAlignVertical.top,
maxLength: 1000,
minLines: null,
maxLines: null,
expands: true,
hintText: s.option_desc_hint_text,
onChanged: (value) {
context.read<CreatePlanCubit>().setOptionDescription(value);
},
),
),
SizedBox(height: 12),
Row(
children: [
Text(
s.you_will_get,
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
softWrap: true,
style: TextStyles.textSMedium.copyWith(color: appTheme.black),
),
SizedBox(width: 4),
_PriceExplanationWidget(),
],
),
SizedBox(height: 4),
CustomTextFormField(
controller: creatorPriceController,
onChanged: (value) {
double? price = double.tryParse(value.replaceAll('₽', ''));
if (price != null) {
price = price * 1.2;
customerPriceController.text = price.toStringAsFixed(2);
context.read<CreatePlanCubit>().setPrice(price);
}
},
maxLength: 20,
),
SizedBox(height: 12),
Row(
children: [
Text(
s.customer_price,
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
softWrap: true,
style: TextStyles.textSMedium.copyWith(color: appTheme.black),
),
SizedBox(width: 4),
_PriceExplanationWidget(),
],
),
SizedBox(height: 4),
CustomTextFormField(
controller: customerPriceController,
textInputType: TextInputType.numberWithOptions(decimal: true),
onChanged: (value) {
final price = double.tryParse(value.replaceAll('₽', ''));
if (price != null) {
creatorPriceController.text = (price * 0.8).toStringAsFixed(2);
context.read<CreatePlanCubit>().setPrice(price);
}
},
maxLength: 20,
),
SizedBox(height: 10),
Text(
s.minimal_customer_price,
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
softWrap: true,
style: TextStyles.textSMedium.copyWith(color: appTheme.black),
),
SizedBox(height: 16),
CustomDivider(),
SizedBox(height: 16),
Text(
s.option_content,
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
softWrap: true,
style: TextStyles.textSMedium.copyWith(color: appTheme.black),
),
SizedBox(height: 4),
ListView.separated(
padding: EdgeInsets.zero,
separatorBuilder: (context, index) => SizedBox(height: 8),
reverse: false,
itemBuilder: (context, index) {
final items = state.planData.options[selectedOptionIndex].items;
if (items.isEmpty) {
return AddItemWidget(
index: index,
canBeDeleted: false,
enableHint: true,
items: items,
);
} else {
if (index < items.length) {
return AddItemWidget(
canBeDeleted: true,
enableHint: false,
index: index,
items: items,
);
} else {
return AddItemWidget(
canBeDeleted: false,
enableHint: false,
index: index,
items: items,
);
}
}
},
itemCount: state.planData.options[selectedOptionIndex].items.length + 1,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
),
SizedBox(height: 16),
CustomDivider(),
SizedBox(height: 16),
Row(
children: [
Checkbox(
value: isChecked,
activeColor: appTheme.gray,
checkColor: appTheme.gray,
fillColor: WidgetStatePropertyAll(Colors.transparent),
side: WidgetStateBorderSide.resolveWith(
(Set<WidgetState> states) {
return BorderSide(width: 1, color: appTheme.gray);
},
),
onChanged: (bool? value) {
setState(() {
isChecked = value ?? false;
});
},
),
Expanded(
child: Text(
s.option_personal_diet_desc,
style: TextStyles.textMMedium.copyWith(color: appTheme.black),
),
),
],
),
],
),
);
},
);
}
}
}
class _PriceExplanationWidget extends StatefulWidget {
const _PriceExplanationWidget();
@override
State<_PriceExplanationWidget> createState() => _PriceExplanationWidgetState();
}
class _PriceExplanationWidgetState extends State<_PriceExplanationWidget> {
bool visible = false;
@override
Widget build(BuildContext context) {
final s = S.of(context);
return PortalTarget(
closeDuration: Duration(milliseconds: 300),
portalFollower: AnimatedContainer(
padding: EdgeInsets.all(10),
duration: const Duration(milliseconds: 300),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
color: visible ? appTheme.black : Colors.transparent,
),
child: AnimatedDefaultTextStyle(
style: TextStyles.textMMediumAuto.copyWith(
color: visible ? appTheme.whiteA700 : Colors.transparent,
),
duration: const Duration(milliseconds: 300),
child: Text(
s.price_explanation,
),
),
),
visible: visible,
anchor: Aligned(
shiftToWithinBound: AxisFlag(x: true, y: true),
follower: Alignment.bottomLeft,
target: Alignment.topRight,
),
child: GestureDetector(
onTap: () {
setState(() {
visible = !visible;
});
},
child: SvgPicture.asset('assets/icons/question_mark.svg', height: 12, width: 12),
),
);
}
}

View File

@@ -61,7 +61,7 @@ class _AnimatedOptionButton extends StatelessWidget {
return GestureDetector(
onTap: onTap,
child: AnimatedContainer(
duration: const Duration(milliseconds: 200),
duration: const Duration(milliseconds: 300),
height: 40,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(100),
@@ -69,7 +69,7 @@ class _AnimatedOptionButton extends StatelessWidget {
),
child: Center(
child: AnimatedDefaultTextStyle(
duration: const Duration(milliseconds: 200),
duration: const Duration(milliseconds: 300),
style: TextStyles.textMSemibold.copyWith(
color: isSelected ? appTheme.whiteA700 : appTheme.black,
),

View File

@@ -1,25 +1,47 @@
import 'package:eatvio_app/core/theme/theme_helper.dart';
import 'package:eatvio_app/features/create_plan/presentation/cubit/create_plan_cubit.dart';
import 'package:eatvio_app/features/create_plan/presentation/cubit/create_plan_state.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class SelectExactOptionWidget extends StatelessWidget {
class SelectExactOptionWidget extends StatefulWidget {
const SelectExactOptionWidget({super.key});
@override
State<SelectExactOptionWidget> createState() => _SelectExactOptionWidgetState();
}
class _SelectExactOptionWidgetState extends State<SelectExactOptionWidget> {
@override
Widget build(BuildContext context) {
return Container(
width: 140,
height: 48,
decoration: BoxDecoration(
color: appTheme.black,
borderRadius: BorderRadius.circular(100),
),
child: Row(
children: [
_OptionButton(isSelected: true, text: '1'),
_OptionButton(isSelected: true, text: '2'),
_OptionButton(isSelected: true, text: '3'),
],
),
return BlocBuilder<CreatePlanCubit, CreatePlanState>(
builder: (context, state) {
final selectedIndex = state.selectedOptionIndex;
return Container(
padding: EdgeInsets.all(4),
width: 140,
height: 48,
decoration: BoxDecoration(
color: appTheme.black,
borderRadius: BorderRadius.circular(100),
),
child: Row(
children: [
...List.generate(
3,
(index) => Expanded(
child: GestureDetector(
onTap: () {
context.read<CreatePlanCubit>().setSelectedOptionIndex(index);
},
child: _OptionButton(isSelected: selectedIndex == index, text: '${index + 1}'),
),
),
),
],
),
);
},
);
}
}
@@ -30,13 +52,21 @@ class _OptionButton extends StatelessWidget {
final String text;
@override
Widget build(BuildContext context) {
return Container(
return AnimatedContainer(
duration: const Duration(milliseconds: 300),
decoration: BoxDecoration(
color: appTheme.whiteA700,
color: isSelected ? appTheme.whiteA700 : Colors.transparent,
shape: BoxShape.circle,
),
child: Text(text),
child: Center(
child: AnimatedDefaultTextStyle(
duration: const Duration(milliseconds: 300),
style: TextStyle(color: isSelected ? appTheme.black : appTheme.whiteA700),
child: Text(
text,
),
),
),
);
}
}

View File

@@ -1,10 +1,9 @@
import 'dart:async';
import 'dart:developer';
import 'package:easy_debounce/easy_debounce.dart';
import 'package:eatvio_app/core/utils/toasts.dart';
import 'package:eatvio_app/features/diets/repositories/diet_repository.dart';
import 'package:eatvio_app/features/diets/presentation/bloc/about_diet_state.dart';
import 'package:eatvio_app/features/diets/presentation/cubit/about_diet_state.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class AboutDietCubit extends Cubit<AboutDietState> {

View File

@@ -8,8 +8,8 @@ import 'package:eatvio_app/core/widgets/bookmark_button.dart';
import 'package:eatvio_app/core/widgets/custom_divider.dart';
import 'package:eatvio_app/core/widgets/diet_info_row.dart';
import 'package:eatvio_app/core/widgets/loader.dart';
import 'package:eatvio_app/features/diets/presentation/bloc/about_diet_cubit.dart';
import 'package:eatvio_app/features/diets/presentation/bloc/about_diet_state.dart';
import 'package:eatvio_app/features/diets/presentation/cubit/about_diet_cubit.dart';
import 'package:eatvio_app/features/diets/presentation/cubit/about_diet_state.dart';
import 'package:eatvio_app/features/diets/presentation/widgets/author_card.dart';
import 'package:eatvio_app/core/widgets/cpfc_container.dart';
import 'package:eatvio_app/features/diets/presentation/widgets/expandable_text.dart';

View File

@@ -1,6 +1,6 @@
import 'package:eatvio_app/core/widgets/bottom_sheet_handler_bar.dart';
import 'package:eatvio_app/core/widgets/custom_divider.dart';
import 'package:eatvio_app/features/diets/presentation/bloc/about_diet_cubit.dart';
import 'package:eatvio_app/features/diets/presentation/cubit/about_diet_cubit.dart';
import 'package:eatvio_app/features/diets/presentation/widgets/calendar_widget.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:eatvio_app/core/theme/custom_text_style.dart';

View File

@@ -34,7 +34,7 @@ class PlanModel with _$PlanModel {
@JsonKey(name: "author") required Author author,
@JsonKey(name: "total_likes") required int totalLikes,
@JsonKey(name: "total_views") required int totalViews,
@JsonKey(name: "total_comments") required int totalComments,
@JsonKey(name: "total_comments") required int totalComments,
}) = _PlanModel;
factory PlanModel.fromJson(Map<String, dynamic> json) => _$PlanModelFromJson(json);
@@ -51,7 +51,7 @@ class PacketOptions with _$PacketOptions {
factory PacketOptions.fromJson(Map<String, dynamic> json) => _$PacketOptionsFromJson(json);
factory PacketOptions.empty() => PacketOptions(items: [], price: -1, short: '', description: '');
factory PacketOptions.empty() => PacketOptions(items: [], price: 1200, short: '', description: '');
}
@freezed

View File

@@ -0,0 +1,68 @@
import 'package:eatvio_app/features/feed/presentation/bloc/plans_cubit/plans_state.dart';
import 'package:eatvio_app/features/feed/repositories/feed_repository.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class PlansCubit extends Cubit<PlansState> {
final FeedRepository feedRepository;
int currentPage = 1;
late int lastPage;
bool isLoading = false;
String? _query;
PlansCubit({
required this.feedRepository,
}) : super(PlansState.initial());
loadPlans({
String? query,
}) async {
try {
_query = query;
final plansPagination = await feedRepository.getPlans(
query: query,
);
lastPage = plansPagination.meta.lastPage;
emit(
state.copyWith(
plans: plansPagination.data,
errorMessage: null,
isLoading: false,
),
);
} catch (e) {
emit(state.copyWith(errorMessage: e.toString()));
}
}
loadNextPage() async {
if (currentPage < lastPage && !isLoading) {
isLoading = true;
emit((state.copyWith(isLoading: isLoading, errorMessage: null)));
try {
if (currentPage < lastPage) {
currentPage++;
final plansPagination = await feedRepository.getPlans(
page: currentPage,
query: _query,
);
isLoading = false;
emit(
state.copyWith(
plans: [
...state.plans,
...plansPagination.data,
],
isLoading: isLoading,
errorMessage: null,
),
);
}
} catch (e) {
emit(state.copyWith(errorMessage: e.toString()));
}
}
}
}

View File

@@ -0,0 +1,19 @@
import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'plans_state.freezed.dart';
@freezed
abstract class PlansState with _$PlansState {
const factory PlansState({
required bool isLoading,
required List<PlanModel> plans,
required String? errorMessage,
}) = _PlansState;
factory PlansState.initial() => const _PlansState(
isLoading: true,
plans: [],
errorMessage: null,
);
}

View File

@@ -0,0 +1,191 @@
// 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 'plans_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 _$PlansState {
bool get isLoading => throw _privateConstructorUsedError;
List<PlanModel> get plans => throw _privateConstructorUsedError;
String? get errorMessage => throw _privateConstructorUsedError;
/// Create a copy of PlansState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$PlansStateCopyWith<PlansState> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $PlansStateCopyWith<$Res> {
factory $PlansStateCopyWith(
PlansState value, $Res Function(PlansState) then) =
_$PlansStateCopyWithImpl<$Res, PlansState>;
@useResult
$Res call({bool isLoading, List<PlanModel> plans, String? errorMessage});
}
/// @nodoc
class _$PlansStateCopyWithImpl<$Res, $Val extends PlansState>
implements $PlansStateCopyWith<$Res> {
_$PlansStateCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of PlansState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? isLoading = null,
Object? plans = null,
Object? errorMessage = freezed,
}) {
return _then(_value.copyWith(
isLoading: null == isLoading
? _value.isLoading
: isLoading // ignore: cast_nullable_to_non_nullable
as bool,
plans: null == plans
? _value.plans
: plans // ignore: cast_nullable_to_non_nullable
as List<PlanModel>,
errorMessage: freezed == errorMessage
? _value.errorMessage
: errorMessage // ignore: cast_nullable_to_non_nullable
as String?,
) as $Val);
}
}
/// @nodoc
abstract class _$$PlansStateImplCopyWith<$Res>
implements $PlansStateCopyWith<$Res> {
factory _$$PlansStateImplCopyWith(
_$PlansStateImpl value, $Res Function(_$PlansStateImpl) then) =
__$$PlansStateImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({bool isLoading, List<PlanModel> plans, String? errorMessage});
}
/// @nodoc
class __$$PlansStateImplCopyWithImpl<$Res>
extends _$PlansStateCopyWithImpl<$Res, _$PlansStateImpl>
implements _$$PlansStateImplCopyWith<$Res> {
__$$PlansStateImplCopyWithImpl(
_$PlansStateImpl _value, $Res Function(_$PlansStateImpl) _then)
: super(_value, _then);
/// Create a copy of PlansState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? isLoading = null,
Object? plans = null,
Object? errorMessage = freezed,
}) {
return _then(_$PlansStateImpl(
isLoading: null == isLoading
? _value.isLoading
: isLoading // ignore: cast_nullable_to_non_nullable
as bool,
plans: null == plans
? _value._plans
: plans // ignore: cast_nullable_to_non_nullable
as List<PlanModel>,
errorMessage: freezed == errorMessage
? _value.errorMessage
: errorMessage // ignore: cast_nullable_to_non_nullable
as String?,
));
}
}
/// @nodoc
class _$PlansStateImpl implements _PlansState {
const _$PlansStateImpl(
{required this.isLoading,
required final List<PlanModel> plans,
required this.errorMessage})
: _plans = plans;
@override
final bool isLoading;
final List<PlanModel> _plans;
@override
List<PlanModel> get plans {
if (_plans is EqualUnmodifiableListView) return _plans;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_plans);
}
@override
final String? errorMessage;
@override
String toString() {
return 'PlansState(isLoading: $isLoading, plans: $plans, errorMessage: $errorMessage)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$PlansStateImpl &&
(identical(other.isLoading, isLoading) ||
other.isLoading == isLoading) &&
const DeepCollectionEquality().equals(other._plans, _plans) &&
(identical(other.errorMessage, errorMessage) ||
other.errorMessage == errorMessage));
}
@override
int get hashCode => Object.hash(runtimeType, isLoading,
const DeepCollectionEquality().hash(_plans), errorMessage);
/// Create a copy of PlansState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$PlansStateImplCopyWith<_$PlansStateImpl> get copyWith =>
__$$PlansStateImplCopyWithImpl<_$PlansStateImpl>(this, _$identity);
}
abstract class _PlansState implements PlansState {
const factory _PlansState(
{required final bool isLoading,
required final List<PlanModel> plans,
required final String? errorMessage}) = _$PlansStateImpl;
@override
bool get isLoading;
@override
List<PlanModel> get plans;
@override
String? get errorMessage;
/// Create a copy of PlansState
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$PlansStateImplCopyWith<_$PlansStateImpl> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@@ -16,8 +16,8 @@ import 'package:eatvio_app/features/feed/presentation/widgets/filter_badge.dart'
import 'package:eatvio_app/features/feed/presentation/widgets/plan_widget.dart';
import 'package:eatvio_app/features/feed/presentation/widgets/recipes_widget.dart';
import 'package:eatvio_app/features/feed/presentation/widgets/tags_modal_widget.dart';
import 'package:eatvio_app/features/plans/presentation/bloc/plans_cubit/plans_cubit.dart';
import 'package:eatvio_app/features/plans/presentation/bloc/plans_cubit/plans_state.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/plans_cubit/plans_cubit.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/plans_cubit/plans_state.dart';
import 'package:eatvio_app/core/locator_service.dart';
import 'package:eatvio_app/core/theme/theme_helper.dart';
import 'package:flutter/material.dart';
@@ -76,7 +76,7 @@ class _FeedScreenState extends State<FeedScreen> {
_onScrollPlans() {
if (plansScrollController.offset >= plansScrollController.position.maxScrollExtent && !plansScrollController.position.outOfRange) {
// plansCubit.loadNextPage();
plansCubit.loadNextPage();
}
}
@@ -119,11 +119,13 @@ class _FeedScreenState extends State<FeedScreen> {
),
backgroundColor: Colors.grey.shade200,
body: NestedScrollView(
controller: _selectedChipIndex == 0
? blogPostsScrollController
: _selectedChipIndex == 1
? recipesScrollController
: dietsScrollController,
controller: switch (_selectedChipIndex) {
0 => blogPostsScrollController,
1 => recipesScrollController,
2 => dietsScrollController,
3 => plansScrollController,
_ => blogPostsScrollController
},
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return [
SliverAppBar(
@@ -317,35 +319,34 @@ class _FeedScreenState extends State<FeedScreen> {
onRefresh: () => plansCubit.loadPlans(),
child: BlocBuilder<PlansCubit, PlansState>(
builder: (BuildContext context, PlansState state) {
if (state is PlansStateLoaded) {
return ListView.separated(
padding: EdgeInsets.symmetric(vertical: 8),
shrinkWrap: true,
physics: BouncingScrollPhysics(),
itemBuilder: (context, index) {
return PlanWidget(planModel: state.plansModel.data[index]);
},
separatorBuilder: (context, index) {
return SizedBox(height: 8);
},
itemCount: state.plansModel.data.length,
if (state.isLoading) {
return Scaffold(
backgroundColor: Colors.grey.shade200,
body: const Loader(),
);
} else if (state is PlansStateError) {
} else if (state.errorMessage != null) {
return Scaffold(
backgroundColor: Colors.grey.shade200,
body: Padding(
padding: const EdgeInsets.all(16),
child: Center(
child: Text(state.errorMessage),
child: Text(state.errorMessage ?? ''),
),
),
);
} else {
return Scaffold(
backgroundColor: Colors.grey.shade200,
body: const Loader(),
);
}
return ListView.separated(
padding: EdgeInsets.symmetric(vertical: 8),
shrinkWrap: true,
physics: BouncingScrollPhysics(),
itemBuilder: (context, index) {
return PlanWidget(planModel: state.plans[index]);
},
separatorBuilder: (context, index) {
return SizedBox(height: 8);
},
itemCount: state.plans.length,
);
},
),
),

View File

@@ -1,6 +1,6 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:eatvio_app/core/const.dart';
import 'package:eatvio_app/features/plans/models/plan_pagination_model.dart';
import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_html/flutter_html.dart';
import 'package:go_router/go_router.dart';

View File

@@ -1,6 +1,7 @@
import 'package:eatvio_app/features/feed/models/comment_model.dart';
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
import 'package:eatvio_app/features/feed/models/feed_blog_post_settings_model.dart';
import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart';
import 'package:eatvio_app/features/feed/models/recipes_model.dart';
import 'package:eatvio_app/features/feed/services/feed_service.dart';
@@ -62,6 +63,22 @@ class FeedRepository {
}
}
Future<PlanPaginationModel> getPlans({
int page = 1,
String? query,
String? types,
int? duration,
String? sorting,
}) async {
try {
return (await feedService.getPlans(
page: page,
));
} catch (e) {
rethrow;
}
}
Future<CommentModel> getBlogPostComments({
required String id,
}) async {

View File

@@ -2,6 +2,7 @@ import 'package:dio/dio.dart';
import 'package:eatvio_app/features/feed/models/comment_model.dart';
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
import 'package:eatvio_app/features/feed/models/feed_blog_post_settings_model.dart';
import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart';
import 'package:eatvio_app/features/feed/models/recipes_pagination_model.dart';
import 'package:retrofit/retrofit.dart';
@@ -27,10 +28,15 @@ abstract class FeedService {
@GET('/api/diets/index')
Future<DietsPagination> getDiets({
@Query('page') required int page,
@Query('filters[name][\$startsWith]') String? query,
@Query('filters[type][\$contains]') String? types,
@Query('filters[duration][\$eq]') int? duration,
@Query('sort') String? sorting,
@Query('filters[name][\$startsWith]') String? query,
@Query('filters[type][\$contains]') String? types,
@Query('filters[duration][\$eq]') int? duration,
@Query('sort') String? sorting,
});
@GET('/api/plans/index')
Future<PlanPaginationModel> getPlans({
@Query('page') required int page,
});
@GET('/api/blogPosts/{id}/comments/show')
@@ -77,6 +83,5 @@ abstract class FeedService {
@POST('/api/blogPosts/{id}/unliked')
Future<void> unlikedBlogPost({
@Path() required int id,
});
});
}

View File

@@ -149,6 +149,39 @@ class _FeedService implements FeedService {
return _value;
}
@override
Future<PlanPaginationModel> getPlans({required int page}) async {
final _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{r'page': page};
final _headers = <String, dynamic>{};
const Map<String, dynamic>? _data = null;
final _options = _setStreamType<PlanPaginationModel>(Options(
method: 'GET',
headers: _headers,
extra: _extra,
)
.compose(
_dio.options,
'/api/plans/index',
queryParameters: queryParameters,
data: _data,
)
.copyWith(
baseUrl: _combineBaseUrls(
_dio.options.baseUrl,
baseUrl,
)));
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
late PlanPaginationModel _value;
try {
_value = PlanPaginationModel.fromJson(_result.data!);
} on Object catch (e, s) {
errorLogger?.logError(e, s, _options);
rethrow;
}
return _value;
}
@override
Future<CommentModel> getBlogPostComments({required String id}) async {
final _extra = <String, dynamic>{};

View File

@@ -1,19 +0,0 @@
import 'package:eatvio_app/features/plans/presentation/bloc/plans_cubit/plans_state.dart';
import 'package:eatvio_app/features/plans/repositories/plans_repository.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class PlansCubit extends Cubit<PlansState> {
final PlansRepository plansRepository;
PlansCubit({
required this.plansRepository,
}) : super(PlansState.loading());
loadPlans() async {
try {
emit(PlansState.loaded(plansModel: await plansRepository.getPlans()));
} catch (e) {
emit(PlansState.error(errorMessage: e.toString()));
}
}
}

View File

@@ -1,19 +0,0 @@
import 'package:eatvio_app/features/plans/models/plan_pagination_model.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'plans_state.freezed.dart';
@freezed
abstract class PlansState with _$PlansState {
const factory PlansState() = _PlansState;
const factory PlansState.loading() = PlansStateLoading;
const factory PlansState.loaded({
required PlanPaginationModel plansModel,
}) = PlansStateLoaded;
const factory PlansState.error({
required String errorMessage,
}) = PlansStateError;
}

View File

@@ -1,646 +0,0 @@
// 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 'plans_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 _$PlansState {
@optionalTypeArgs
TResult when<TResult extends Object?>(
TResult Function() $default, {
required TResult Function() loading,
required TResult Function(PlanPaginationModel plansModel) loaded,
required TResult Function(String errorMessage) error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>(
TResult? Function()? $default, {
TResult? Function()? loading,
TResult? Function(PlanPaginationModel plansModel)? loaded,
TResult? Function(String errorMessage)? error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>(
TResult Function()? $default, {
TResult Function()? loading,
TResult Function(PlanPaginationModel plansModel)? loaded,
TResult Function(String errorMessage)? error,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>(
TResult Function(_PlansState value) $default, {
required TResult Function(PlansStateLoading value) loading,
required TResult Function(PlansStateLoaded value) loaded,
required TResult Function(PlansStateError value) error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>(
TResult? Function(_PlansState value)? $default, {
TResult? Function(PlansStateLoading value)? loading,
TResult? Function(PlansStateLoaded value)? loaded,
TResult? Function(PlansStateError value)? error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>(
TResult Function(_PlansState value)? $default, {
TResult Function(PlansStateLoading value)? loading,
TResult Function(PlansStateLoaded value)? loaded,
TResult Function(PlansStateError value)? error,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $PlansStateCopyWith<$Res> {
factory $PlansStateCopyWith(
PlansState value, $Res Function(PlansState) then) =
_$PlansStateCopyWithImpl<$Res, PlansState>;
}
/// @nodoc
class _$PlansStateCopyWithImpl<$Res, $Val extends PlansState>
implements $PlansStateCopyWith<$Res> {
_$PlansStateCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of PlansState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
abstract class _$$PlansStateImplCopyWith<$Res> {
factory _$$PlansStateImplCopyWith(
_$PlansStateImpl value, $Res Function(_$PlansStateImpl) then) =
__$$PlansStateImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$PlansStateImplCopyWithImpl<$Res>
extends _$PlansStateCopyWithImpl<$Res, _$PlansStateImpl>
implements _$$PlansStateImplCopyWith<$Res> {
__$$PlansStateImplCopyWithImpl(
_$PlansStateImpl _value, $Res Function(_$PlansStateImpl) _then)
: super(_value, _then);
/// Create a copy of PlansState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$PlansStateImpl implements _PlansState {
const _$PlansStateImpl();
@override
String toString() {
return 'PlansState()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$PlansStateImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>(
TResult Function() $default, {
required TResult Function() loading,
required TResult Function(PlanPaginationModel plansModel) loaded,
required TResult Function(String errorMessage) error,
}) {
return $default();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>(
TResult? Function()? $default, {
TResult? Function()? loading,
TResult? Function(PlanPaginationModel plansModel)? loaded,
TResult? Function(String errorMessage)? error,
}) {
return $default?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>(
TResult Function()? $default, {
TResult Function()? loading,
TResult Function(PlanPaginationModel plansModel)? 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(_PlansState value) $default, {
required TResult Function(PlansStateLoading value) loading,
required TResult Function(PlansStateLoaded value) loaded,
required TResult Function(PlansStateError value) error,
}) {
return $default(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>(
TResult? Function(_PlansState value)? $default, {
TResult? Function(PlansStateLoading value)? loading,
TResult? Function(PlansStateLoaded value)? loaded,
TResult? Function(PlansStateError value)? error,
}) {
return $default?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>(
TResult Function(_PlansState value)? $default, {
TResult Function(PlansStateLoading value)? loading,
TResult Function(PlansStateLoaded value)? loaded,
TResult Function(PlansStateError value)? error,
required TResult orElse(),
}) {
if ($default != null) {
return $default(this);
}
return orElse();
}
}
abstract class _PlansState implements PlansState {
const factory _PlansState() = _$PlansStateImpl;
}
/// @nodoc
abstract class _$$PlansStateLoadingImplCopyWith<$Res> {
factory _$$PlansStateLoadingImplCopyWith(_$PlansStateLoadingImpl value,
$Res Function(_$PlansStateLoadingImpl) then) =
__$$PlansStateLoadingImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$PlansStateLoadingImplCopyWithImpl<$Res>
extends _$PlansStateCopyWithImpl<$Res, _$PlansStateLoadingImpl>
implements _$$PlansStateLoadingImplCopyWith<$Res> {
__$$PlansStateLoadingImplCopyWithImpl(_$PlansStateLoadingImpl _value,
$Res Function(_$PlansStateLoadingImpl) _then)
: super(_value, _then);
/// Create a copy of PlansState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$PlansStateLoadingImpl implements PlansStateLoading {
const _$PlansStateLoadingImpl();
@override
String toString() {
return 'PlansState.loading()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$PlansStateLoadingImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>(
TResult Function() $default, {
required TResult Function() loading,
required TResult Function(PlanPaginationModel plansModel) loaded,
required TResult Function(String errorMessage) error,
}) {
return loading();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>(
TResult? Function()? $default, {
TResult? Function()? loading,
TResult? Function(PlanPaginationModel plansModel)? loaded,
TResult? Function(String errorMessage)? error,
}) {
return loading?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>(
TResult Function()? $default, {
TResult Function()? loading,
TResult Function(PlanPaginationModel plansModel)? 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(_PlansState value) $default, {
required TResult Function(PlansStateLoading value) loading,
required TResult Function(PlansStateLoaded value) loaded,
required TResult Function(PlansStateError value) error,
}) {
return loading(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>(
TResult? Function(_PlansState value)? $default, {
TResult? Function(PlansStateLoading value)? loading,
TResult? Function(PlansStateLoaded value)? loaded,
TResult? Function(PlansStateError value)? error,
}) {
return loading?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>(
TResult Function(_PlansState value)? $default, {
TResult Function(PlansStateLoading value)? loading,
TResult Function(PlansStateLoaded value)? loaded,
TResult Function(PlansStateError value)? error,
required TResult orElse(),
}) {
if (loading != null) {
return loading(this);
}
return orElse();
}
}
abstract class PlansStateLoading implements PlansState {
const factory PlansStateLoading() = _$PlansStateLoadingImpl;
}
/// @nodoc
abstract class _$$PlansStateLoadedImplCopyWith<$Res> {
factory _$$PlansStateLoadedImplCopyWith(_$PlansStateLoadedImpl value,
$Res Function(_$PlansStateLoadedImpl) then) =
__$$PlansStateLoadedImplCopyWithImpl<$Res>;
@useResult
$Res call({PlanPaginationModel plansModel});
$PlanPaginationModelCopyWith<$Res> get plansModel;
}
/// @nodoc
class __$$PlansStateLoadedImplCopyWithImpl<$Res>
extends _$PlansStateCopyWithImpl<$Res, _$PlansStateLoadedImpl>
implements _$$PlansStateLoadedImplCopyWith<$Res> {
__$$PlansStateLoadedImplCopyWithImpl(_$PlansStateLoadedImpl _value,
$Res Function(_$PlansStateLoadedImpl) _then)
: super(_value, _then);
/// Create a copy of PlansState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? plansModel = null,
}) {
return _then(_$PlansStateLoadedImpl(
plansModel: null == plansModel
? _value.plansModel
: plansModel // ignore: cast_nullable_to_non_nullable
as PlanPaginationModel,
));
}
/// Create a copy of PlansState
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$PlanPaginationModelCopyWith<$Res> get plansModel {
return $PlanPaginationModelCopyWith<$Res>(_value.plansModel, (value) {
return _then(_value.copyWith(plansModel: value));
});
}
}
/// @nodoc
class _$PlansStateLoadedImpl implements PlansStateLoaded {
const _$PlansStateLoadedImpl({required this.plansModel});
@override
final PlanPaginationModel plansModel;
@override
String toString() {
return 'PlansState.loaded(plansModel: $plansModel)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$PlansStateLoadedImpl &&
(identical(other.plansModel, plansModel) ||
other.plansModel == plansModel));
}
@override
int get hashCode => Object.hash(runtimeType, plansModel);
/// Create a copy of PlansState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$PlansStateLoadedImplCopyWith<_$PlansStateLoadedImpl> get copyWith =>
__$$PlansStateLoadedImplCopyWithImpl<_$PlansStateLoadedImpl>(
this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>(
TResult Function() $default, {
required TResult Function() loading,
required TResult Function(PlanPaginationModel plansModel) loaded,
required TResult Function(String errorMessage) error,
}) {
return loaded(plansModel);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>(
TResult? Function()? $default, {
TResult? Function()? loading,
TResult? Function(PlanPaginationModel plansModel)? loaded,
TResult? Function(String errorMessage)? error,
}) {
return loaded?.call(plansModel);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>(
TResult Function()? $default, {
TResult Function()? loading,
TResult Function(PlanPaginationModel plansModel)? loaded,
TResult Function(String errorMessage)? error,
required TResult orElse(),
}) {
if (loaded != null) {
return loaded(plansModel);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>(
TResult Function(_PlansState value) $default, {
required TResult Function(PlansStateLoading value) loading,
required TResult Function(PlansStateLoaded value) loaded,
required TResult Function(PlansStateError value) error,
}) {
return loaded(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>(
TResult? Function(_PlansState value)? $default, {
TResult? Function(PlansStateLoading value)? loading,
TResult? Function(PlansStateLoaded value)? loaded,
TResult? Function(PlansStateError value)? error,
}) {
return loaded?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>(
TResult Function(_PlansState value)? $default, {
TResult Function(PlansStateLoading value)? loading,
TResult Function(PlansStateLoaded value)? loaded,
TResult Function(PlansStateError value)? error,
required TResult orElse(),
}) {
if (loaded != null) {
return loaded(this);
}
return orElse();
}
}
abstract class PlansStateLoaded implements PlansState {
const factory PlansStateLoaded(
{required final PlanPaginationModel plansModel}) = _$PlansStateLoadedImpl;
PlanPaginationModel get plansModel;
/// Create a copy of PlansState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$PlansStateLoadedImplCopyWith<_$PlansStateLoadedImpl> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class _$$PlansStateErrorImplCopyWith<$Res> {
factory _$$PlansStateErrorImplCopyWith(_$PlansStateErrorImpl value,
$Res Function(_$PlansStateErrorImpl) then) =
__$$PlansStateErrorImplCopyWithImpl<$Res>;
@useResult
$Res call({String errorMessage});
}
/// @nodoc
class __$$PlansStateErrorImplCopyWithImpl<$Res>
extends _$PlansStateCopyWithImpl<$Res, _$PlansStateErrorImpl>
implements _$$PlansStateErrorImplCopyWith<$Res> {
__$$PlansStateErrorImplCopyWithImpl(
_$PlansStateErrorImpl _value, $Res Function(_$PlansStateErrorImpl) _then)
: super(_value, _then);
/// Create a copy of PlansState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? errorMessage = null,
}) {
return _then(_$PlansStateErrorImpl(
errorMessage: null == errorMessage
? _value.errorMessage
: errorMessage // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
/// @nodoc
class _$PlansStateErrorImpl implements PlansStateError {
const _$PlansStateErrorImpl({required this.errorMessage});
@override
final String errorMessage;
@override
String toString() {
return 'PlansState.error(errorMessage: $errorMessage)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$PlansStateErrorImpl &&
(identical(other.errorMessage, errorMessage) ||
other.errorMessage == errorMessage));
}
@override
int get hashCode => Object.hash(runtimeType, errorMessage);
/// Create a copy of PlansState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$PlansStateErrorImplCopyWith<_$PlansStateErrorImpl> get copyWith =>
__$$PlansStateErrorImplCopyWithImpl<_$PlansStateErrorImpl>(
this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>(
TResult Function() $default, {
required TResult Function() loading,
required TResult Function(PlanPaginationModel plansModel) 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(PlanPaginationModel plansModel)? 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(PlanPaginationModel plansModel)? 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(_PlansState value) $default, {
required TResult Function(PlansStateLoading value) loading,
required TResult Function(PlansStateLoaded value) loaded,
required TResult Function(PlansStateError value) error,
}) {
return error(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>(
TResult? Function(_PlansState value)? $default, {
TResult? Function(PlansStateLoading value)? loading,
TResult? Function(PlansStateLoaded value)? loaded,
TResult? Function(PlansStateError value)? error,
}) {
return error?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>(
TResult Function(_PlansState value)? $default, {
TResult Function(PlansStateLoading value)? loading,
TResult Function(PlansStateLoaded value)? loaded,
TResult Function(PlansStateError value)? error,
required TResult orElse(),
}) {
if (error != null) {
return error(this);
}
return orElse();
}
}
abstract class PlansStateError implements PlansState {
const factory PlansStateError({required final String errorMessage}) =
_$PlansStateErrorImpl;
String get errorMessage;
/// Create a copy of PlansState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$PlansStateErrorImplCopyWith<_$PlansStateErrorImpl> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@@ -0,0 +1,11 @@
import 'package:eatvio_app/features/plans/presentation/cubit/about_plan_state.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class AboutPlanCubit extends Cubit<AboutPlanState> {
AboutPlanCubit() : super(AboutPlanState.initial());
Future<void> getPlan() async{
}
}

View File

@@ -0,0 +1,18 @@
import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'about_plan_state.freezed.dart';
@freezed
class AboutPlanState with _$AboutPlanState {
const factory AboutPlanState({
required bool isLoading,
required String? error,
required PlanModel? planModel,
}) = _AboutPlanState;
factory AboutPlanState.initial() => const AboutPlanState(isLoading: false, error: null, planModel: null);
}

View File

@@ -0,0 +1,201 @@
// 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 'about_plan_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 _$AboutPlanState {
bool get isLoading => throw _privateConstructorUsedError;
String? get error => throw _privateConstructorUsedError;
PlanModel? get planModel => throw _privateConstructorUsedError;
/// Create a copy of AboutPlanState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$AboutPlanStateCopyWith<AboutPlanState> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $AboutPlanStateCopyWith<$Res> {
factory $AboutPlanStateCopyWith(
AboutPlanState value, $Res Function(AboutPlanState) then) =
_$AboutPlanStateCopyWithImpl<$Res, AboutPlanState>;
@useResult
$Res call({bool isLoading, String? error, PlanModel? planModel});
$PlanModelCopyWith<$Res>? get planModel;
}
/// @nodoc
class _$AboutPlanStateCopyWithImpl<$Res, $Val extends AboutPlanState>
implements $AboutPlanStateCopyWith<$Res> {
_$AboutPlanStateCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of AboutPlanState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? isLoading = null,
Object? error = freezed,
Object? planModel = freezed,
}) {
return _then(_value.copyWith(
isLoading: null == isLoading
? _value.isLoading
: isLoading // ignore: cast_nullable_to_non_nullable
as bool,
error: freezed == error
? _value.error
: error // ignore: cast_nullable_to_non_nullable
as String?,
planModel: freezed == planModel
? _value.planModel
: planModel // ignore: cast_nullable_to_non_nullable
as PlanModel?,
) as $Val);
}
/// Create a copy of AboutPlanState
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$PlanModelCopyWith<$Res>? get planModel {
if (_value.planModel == null) {
return null;
}
return $PlanModelCopyWith<$Res>(_value.planModel!, (value) {
return _then(_value.copyWith(planModel: value) as $Val);
});
}
}
/// @nodoc
abstract class _$$AboutPlanStateImplCopyWith<$Res>
implements $AboutPlanStateCopyWith<$Res> {
factory _$$AboutPlanStateImplCopyWith(_$AboutPlanStateImpl value,
$Res Function(_$AboutPlanStateImpl) then) =
__$$AboutPlanStateImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({bool isLoading, String? error, PlanModel? planModel});
@override
$PlanModelCopyWith<$Res>? get planModel;
}
/// @nodoc
class __$$AboutPlanStateImplCopyWithImpl<$Res>
extends _$AboutPlanStateCopyWithImpl<$Res, _$AboutPlanStateImpl>
implements _$$AboutPlanStateImplCopyWith<$Res> {
__$$AboutPlanStateImplCopyWithImpl(
_$AboutPlanStateImpl _value, $Res Function(_$AboutPlanStateImpl) _then)
: super(_value, _then);
/// Create a copy of AboutPlanState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? isLoading = null,
Object? error = freezed,
Object? planModel = freezed,
}) {
return _then(_$AboutPlanStateImpl(
isLoading: null == isLoading
? _value.isLoading
: isLoading // ignore: cast_nullable_to_non_nullable
as bool,
error: freezed == error
? _value.error
: error // ignore: cast_nullable_to_non_nullable
as String?,
planModel: freezed == planModel
? _value.planModel
: planModel // ignore: cast_nullable_to_non_nullable
as PlanModel?,
));
}
}
/// @nodoc
class _$AboutPlanStateImpl implements _AboutPlanState {
const _$AboutPlanStateImpl(
{required this.isLoading, required this.error, required this.planModel});
@override
final bool isLoading;
@override
final String? error;
@override
final PlanModel? planModel;
@override
String toString() {
return 'AboutPlanState(isLoading: $isLoading, error: $error, planModel: $planModel)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$AboutPlanStateImpl &&
(identical(other.isLoading, isLoading) ||
other.isLoading == isLoading) &&
(identical(other.error, error) || other.error == error) &&
(identical(other.planModel, planModel) ||
other.planModel == planModel));
}
@override
int get hashCode => Object.hash(runtimeType, isLoading, error, planModel);
/// Create a copy of AboutPlanState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$AboutPlanStateImplCopyWith<_$AboutPlanStateImpl> get copyWith =>
__$$AboutPlanStateImplCopyWithImpl<_$AboutPlanStateImpl>(
this, _$identity);
}
abstract class _AboutPlanState implements AboutPlanState {
const factory _AboutPlanState(
{required final bool isLoading,
required final String? error,
required final PlanModel? planModel}) = _$AboutPlanStateImpl;
@override
bool get isLoading;
@override
String? get error;
@override
PlanModel? get planModel;
/// Create a copy of AboutPlanState
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$AboutPlanStateImplCopyWith<_$AboutPlanStateImpl> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@@ -1,4 +1,4 @@
import 'package:eatvio_app/features/plans/models/plan_pagination_model.dart';
import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart';
import 'package:flutter/material.dart';
class AboutPlanScreen extends StatelessWidget {

View File

@@ -1,16 +0,0 @@
import 'package:eatvio_app/features/plans/models/plan_pagination_model.dart';
import 'package:eatvio_app/features/plans/services/plans_service.dart';
class PlansRepository {
final PlansService plansService;
const PlansRepository({required this.plansService});
Future<PlanPaginationModel> getPlans() async {
try {
return await plansService.getPlans();
} catch (e) {
rethrow;
}
}
}

View File

@@ -1,13 +0,0 @@
import 'package:dio/dio.dart';
import 'package:eatvio_app/features/plans/models/plan_pagination_model.dart';
import 'package:retrofit/retrofit.dart';
part 'plans_service.g.dart';
@RestApi()
abstract class PlansService {
factory PlansService(Dio dio, {String baseUrl}) = _PlansService;
@GET('/api/plans/index')
Future<PlanPaginationModel> getPlans();
}

View File

@@ -1,86 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'plans_service.dart';
// **************************************************************************
// RetrofitGenerator
// **************************************************************************
// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element,unnecessary_string_interpolations
class _PlansService implements PlansService {
_PlansService(
this._dio, {
this.baseUrl,
this.errorLogger,
});
final Dio _dio;
String? baseUrl;
final ParseErrorLogger? errorLogger;
@override
Future<PlanPaginationModel> getPlans() async {
final _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _headers = <String, dynamic>{};
const Map<String, dynamic>? _data = null;
final _options = _setStreamType<PlanPaginationModel>(Options(
method: 'GET',
headers: _headers,
extra: _extra,
)
.compose(
_dio.options,
'/api/plans/index',
queryParameters: queryParameters,
data: _data,
)
.copyWith(
baseUrl: _combineBaseUrls(
_dio.options.baseUrl,
baseUrl,
)));
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
late PlanPaginationModel _value;
try {
_value = PlanPaginationModel.fromJson(_result.data!);
} on Object catch (e, s) {
errorLogger?.logError(e, s, _options);
rethrow;
}
return _value;
}
RequestOptions _setStreamType<T>(RequestOptions requestOptions) {
if (T != dynamic &&
!(requestOptions.responseType == ResponseType.bytes ||
requestOptions.responseType == ResponseType.stream)) {
if (T == String) {
requestOptions.responseType = ResponseType.plain;
} else {
requestOptions.responseType = ResponseType.json;
}
}
return requestOptions;
}
String _combineBaseUrls(
String dioBaseUrl,
String? baseUrl,
) {
if (baseUrl == null || baseUrl.trim().isEmpty) {
return dioBaseUrl;
}
final url = Uri.parse(baseUrl);
if (url.isAbsolute) {
return url.toString();
}
return Uri.parse(dioBaseUrl).resolveUri(url).toString();
}
}

View File

@@ -71,6 +71,7 @@ class MessageLookup extends MessageLookupByLibrary {
"city": MessageLookupByLibrary.simpleMessage("Город"),
"city_of_living":
MessageLookupByLibrary.simpleMessage("Город проживания"),
"comfort": MessageLookupByLibrary.simpleMessage("Комфорт"),
"comment": MessageLookupByLibrary.simpleMessage("комментарий"),
"comments": MessageLookupByLibrary.simpleMessage("Комментарии"),
"comments_plural": MessageLookupByLibrary.simpleMessage("комментариев"),
@@ -81,6 +82,8 @@ class MessageLookup extends MessageLookupByLibrary {
"copy_link": MessageLookupByLibrary.simpleMessage("Скопировать ссылку"),
"country": MessageLookupByLibrary.simpleMessage("Страна"),
"create_diet": MessageLookupByLibrary.simpleMessage("Создание диеты"),
"customer_price":
MessageLookupByLibrary.simpleMessage("Цена для покупателя"),
"date_of_birth": MessageLookupByLibrary.simpleMessage("Дата рождения"),
"day": MessageLookupByLibrary.simpleMessage("День"),
"days": MessageLookupByLibrary.simpleMessage("дней"),
@@ -101,6 +104,7 @@ class MessageLookup extends MessageLookupByLibrary {
"draft": MessageLookupByLibrary.simpleMessage("Черновик"),
"eating_behavior":
MessageLookupByLibrary.simpleMessage("Пищевое поведение"),
"economy": MessageLookupByLibrary.simpleMessage("Эконом"),
"email": MessageLookupByLibrary.simpleMessage("Элетронная почта"),
"email_empty": MessageLookupByLibrary.simpleMessage(
"Необходимо ввести адрес электронной почты"),
@@ -167,6 +171,8 @@ class MessageLookup extends MessageLookupByLibrary {
"meat_type_desc": MessageLookupByLibrary.simpleMessage(
"Диета с мясом полезная и сбалансированная. Включает в себя нежирное мясо: курицу, индейку, кролика или говядину. В сочетании с овощами получаете все необходимые витамины и минералы. Не забывайте о порциях и старайтесь есть медленно, прислушиваясь к своему организму."),
"milliliter": MessageLookupByLibrary.simpleMessage("мл"),
"minimal_customer_price": MessageLookupByLibrary.simpleMessage(
"Минимальная цена для покупателя: 1200₽"),
"most_new": MessageLookupByLibrary.simpleMessage("Самые новые"),
"most_old": MessageLookupByLibrary.simpleMessage("Самые старые"),
"msg_network_err":
@@ -183,6 +189,17 @@ class MessageLookup extends MessageLookupByLibrary {
"no_account":
MessageLookupByLibrary.simpleMessage("У меня нет аккаунта"),
"one_option": MessageLookupByLibrary.simpleMessage("1 опция"),
"option": MessageLookupByLibrary.simpleMessage("Опция"),
"option_content":
MessageLookupByLibrary.simpleMessage("Содержание опции"),
"option_content_hint_text":
MessageLookupByLibrary.simpleMessage("На связи 7 дней в неделю"),
"option_desc": MessageLookupByLibrary.simpleMessage("Описание опции"),
"option_desc_hint_text": MessageLookupByLibrary.simpleMessage(
"Этот план питания для похудения на 7 дней сбалансированный и разнообразный"),
"option_personal_diet_desc": MessageLookupByLibrary.simpleMessage(
"Опция подразумевает создание индивидуальной диеты"),
"option_title": MessageLookupByLibrary.simpleMessage("Заголовок опции"),
"order": MessageLookupByLibrary.simpleMessage("Порядок"),
"password": MessageLookupByLibrary.simpleMessage("Пароль"),
"password_confirmation":
@@ -215,14 +232,18 @@ class MessageLookup extends MessageLookupByLibrary {
"pressure_is_not_a_number": MessageLookupByLibrary.simpleMessage(
"Все показатели давления должны быть числами"),
"preview": MessageLookupByLibrary.simpleMessage("Превью"),
"price_explanation": MessageLookupByLibrary.simpleMessage(
"Разница в ценах, это комиссия Итвио"),
"profile": MessageLookupByLibrary.simpleMessage("Профиль"),
"proteins": MessageLookupByLibrary.simpleMessage("Белки"),
"publish": MessageLookupByLibrary.simpleMessage("Опубликовать"),
"save": MessageLookupByLibrary.simpleMessage("Сохранить"),
"services": MessageLookupByLibrary.simpleMessage("Оказание услуг"),
"settings": MessageLookupByLibrary.simpleMessage("Настройки"),
"share": MessageLookupByLibrary.simpleMessage("Поделиться"),
"skip": MessageLookupByLibrary.simpleMessage("Пропустить"),
"slim": MessageLookupByLibrary.simpleMessage("Похудение"),
"standard": MessageLookupByLibrary.simpleMessage("Стандарт"),
"startDiet": MessageLookupByLibrary.simpleMessage("Начать диету"),
"tell_your_schedule": MessageLookupByLibrary.simpleMessage(
"Расскажите в свободной форме о том как просыпаетесь, когда едите, когда ложитесь спать:"),
@@ -254,6 +275,7 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("Как вас зовут?"),
"wrong_credentials": MessageLookupByLibrary.simpleMessage(
"Неверные данные пользователя"),
"you_will_get": MessageLookupByLibrary.simpleMessage("Вы получите"),
"your_blood_pressure":
MessageLookupByLibrary.simpleMessage("Ваше артериальное давление?"),
"your_favorite_sports":

View File

@@ -1779,6 +1779,156 @@ class S {
args: [],
);
}
/// `Опция`
String get option {
return Intl.message(
'Опция',
name: 'option',
desc: '',
args: [],
);
}
/// `Оказание услуг`
String get services {
return Intl.message(
'Оказание услуг',
name: 'services',
desc: '',
args: [],
);
}
/// `Эконом`
String get economy {
return Intl.message(
'Эконом',
name: 'economy',
desc: '',
args: [],
);
}
/// `Стандарт`
String get standard {
return Intl.message(
'Стандарт',
name: 'standard',
desc: '',
args: [],
);
}
/// `Комфорт`
String get comfort {
return Intl.message(
'Комфорт',
name: 'comfort',
desc: '',
args: [],
);
}
/// `Заголовок опции`
String get option_title {
return Intl.message(
'Заголовок опции',
name: 'option_title',
desc: '',
args: [],
);
}
/// `Описание опции`
String get option_desc {
return Intl.message(
'Описание опции',
name: 'option_desc',
desc: '',
args: [],
);
}
/// `Этот план питания для похудения на 7 дней сбалансированный и разнообразный`
String get option_desc_hint_text {
return Intl.message(
'Этот план питания для похудения на 7 дней сбалансированный и разнообразный',
name: 'option_desc_hint_text',
desc: '',
args: [],
);
}
/// `Вы получите`
String get you_will_get {
return Intl.message(
'Вы получите',
name: 'you_will_get',
desc: '',
args: [],
);
}
/// `Цена для покупателя`
String get customer_price {
return Intl.message(
'Цена для покупателя',
name: 'customer_price',
desc: '',
args: [],
);
}
/// `Минимальная цена для покупателя: 1200₽`
String get minimal_customer_price {
return Intl.message(
'Минимальная цена для покупателя: 1200₽',
name: 'minimal_customer_price',
desc: '',
args: [],
);
}
/// `Разница в ценах, это комиссия Итвио`
String get price_explanation {
return Intl.message(
'Разница в ценах, это комиссия Итвио',
name: 'price_explanation',
desc: '',
args: [],
);
}
/// `Содержание опции`
String get option_content {
return Intl.message(
'Содержание опции',
name: 'option_content',
desc: '',
args: [],
);
}
/// `На связи 7 дней в неделю`
String get option_content_hint_text {
return Intl.message(
'На связи 7 дней в неделю',
name: 'option_content_hint_text',
desc: '',
args: [],
);
}
/// `Опция подразумевает создание индивидуальной диеты`
String get option_personal_diet_desc {
return Intl.message(
'Опция подразумевает создание индивидуальной диеты',
name: 'option_personal_diet_desc',
desc: '',
args: [],
);
}
}
class AppLocalizationDelegate extends LocalizationsDelegate<S> {

View File

@@ -171,6 +171,20 @@
"plan_desc": "Описание плана",
"plan_desc_example": "Большое подробное, привлекательное описание плана",
"one_option": "1 опция",
"three_options": "3 опции"
"three_options": "3 опции",
"option": "Опция",
"services": "Оказание услуг",
"economy": "Эконом",
"standard": "Стандарт",
"comfort": "Комфорт",
"option_title": "Заголовок опции",
"option_desc": "Описание опции",
"option_desc_hint_text": "Этот план питания для похудения на 7 дней сбалансированный и разнообразный",
"you_will_get": "Вы получите",
"customer_price": "Цена для покупателя",
"minimal_customer_price": "Минимальная цена для покупателя: 1200₽",
"price_explanation": "Разница в ценах, это комиссия Итвио",
"option_content": "Содержание опции",
"option_content_hint_text": "На связи 7 дней в неделю",
"option_personal_diet_desc": "Опция подразумевает создание индивидуальной диеты"
}