forked from eatvio/eatvio_app
added plan pagination and updated plans creation screen
This commit is contained in:
@@ -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(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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(),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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()],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
),
|
||||
|
||||
@@ -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,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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> {
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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>{};
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
11
lib/features/plans/presentation/cubit/about_plan_cubit.dart
Normal file
11
lib/features/plans/presentation/cubit/about_plan_cubit.dart
Normal 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{
|
||||
|
||||
}
|
||||
}
|
||||
18
lib/features/plans/presentation/cubit/about_plan_state.dart
Normal file
18
lib/features/plans/presentation/cubit/about_plan_state.dart
Normal 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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user