forked from eatvio/eatvio_app
feat(plans): plan creating has been completed
This commit is contained in:
@@ -1,56 +1,65 @@
|
||||
import 'package:eatvio_app/core/const.dart';
|
||||
import 'package:eatvio_app/features/create_plan/presentation/cubit/create_plan_state.dart';
|
||||
import 'package:eatvio_app/features/create_plan/repositories/create_plan_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_image_compress/flutter_image_compress.dart';
|
||||
|
||||
class CreatePlanCubit extends Cubit<CreatePlanState> {
|
||||
CreatePlanCubit() : super(CreatePlanState.initial());
|
||||
final CreatePlanRepository createPlanRepository;
|
||||
CreatePlanCubit({required this.createPlanRepository}) : super(CreatePlanState.initial());
|
||||
|
||||
void setDetails(String text) {
|
||||
emit(state.copyWith(planData: state.planData.copyWith(details: text)));
|
||||
validateDetails();
|
||||
}
|
||||
|
||||
void setName(String name) {
|
||||
emit(state.copyWith(planData: state.planData.copyWith(name: name)));
|
||||
validateName();
|
||||
}
|
||||
|
||||
void setOptionTitle(String title) {
|
||||
final options = [...state.planData.options];
|
||||
options[state.selectedOptionIndex ?? 0] = options[state.selectedOptionIndex ?? 0].copyWith(short: title);
|
||||
options[state.selectedOptionIndex ?? 0] = options[state.selectedOptionIndex ?? 0].copyWith(short: title);
|
||||
emit(state.copyWith(planData: state.planData.copyWith(options: options)));
|
||||
validateSelectedOptionTitle();
|
||||
}
|
||||
|
||||
void setPrice(double price){
|
||||
void setPrice(double price) {
|
||||
final selectedOptionIndex = state.selectedOptionIndex ?? 0;
|
||||
final options = [...state.planData.options];
|
||||
options[selectedOptionIndex] = options[selectedOptionIndex].copyWith(price: price);
|
||||
final options = [...state.planData.options];
|
||||
options[selectedOptionIndex] = options[selectedOptionIndex].copyWith(price: price);
|
||||
emit(state.copyWith(planData: state.planData.copyWith(options: options)));
|
||||
validateSelectedOptionPrice();
|
||||
}
|
||||
|
||||
void setOptionDescription(String description) {
|
||||
final options = [...state.planData.options];
|
||||
options[state.selectedOptionIndex ?? 0] = options[state.selectedOptionIndex ?? 0].copyWith(description: description);
|
||||
options[state.selectedOptionIndex ?? 0] = options[state.selectedOptionIndex ?? 0].copyWith(description: description);
|
||||
emit(state.copyWith(planData: state.planData.copyWith(options: options)));
|
||||
validateSelectedOptionDescription();
|
||||
}
|
||||
|
||||
void setOptionContent(String content, index) {
|
||||
final options = [...state.planData.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 {
|
||||
} else {
|
||||
items[index] = content;
|
||||
}
|
||||
options[state.selectedOptionIndex ?? 0] = options[state.selectedOptionIndex ?? 0].copyWith(items: items);
|
||||
options[state.selectedOptionIndex ?? 0] = options[state.selectedOptionIndex ?? 0].copyWith(items: items);
|
||||
emit(state.copyWith(planData: state.planData.copyWith(options: options)));
|
||||
validateSelectedOptionItems();
|
||||
}
|
||||
|
||||
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);
|
||||
options[state.selectedOptionIndex ?? 0] = options[state.selectedOptionIndex ?? 0].copyWith(items: updatedItems);
|
||||
emit(state.copyWith(planData: state.planData.copyWith(options: options)));
|
||||
validateSelectedOptionItems();
|
||||
}
|
||||
|
||||
void setDuration(int index) {
|
||||
@@ -62,10 +71,12 @@ class CreatePlanCubit extends Cubit<CreatePlanState> {
|
||||
),
|
||||
),
|
||||
);
|
||||
validateDuration();
|
||||
}
|
||||
|
||||
void setImage(XFile? image) {
|
||||
emit(state.copyWith(planData: state.planData.copyWith(image: image)));
|
||||
validateImage();
|
||||
}
|
||||
|
||||
void setPlanState(String planState) {
|
||||
@@ -74,9 +85,319 @@ class CreatePlanCubit extends Cubit<CreatePlanState> {
|
||||
|
||||
void setPlanType(List<bool> type) {
|
||||
emit(state.copyWith(planData: state.planData.copyWith(type: type)));
|
||||
if (type.any((elem) => elem)) {
|
||||
validateType();
|
||||
}
|
||||
}
|
||||
|
||||
void setSelectedOptionIndex(int? index) {
|
||||
emit(state.copyWith(selectedOptionIndex: index));
|
||||
}
|
||||
|
||||
bool validateName() {
|
||||
final name = state.planData.name;
|
||||
if (name == null || name.length < 3) {
|
||||
emit(state.copyWith.validationState(titleHasError: true));
|
||||
return false;
|
||||
}
|
||||
emit(state.copyWith.validationState(titleHasError: false));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool validateDetails() {
|
||||
final details = state.planData.details;
|
||||
if (details == null || details.length < 3) {
|
||||
emit(state.copyWith.validationState(descriptionHasError: true));
|
||||
return false;
|
||||
}
|
||||
emit(state.copyWith.validationState(descriptionHasError: false));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool validateDuration() {
|
||||
if (state.planData.duration == null) {
|
||||
emit(state.copyWith.validationState(durationHasError: true));
|
||||
return false;
|
||||
}
|
||||
emit(state.copyWith.validationState(durationHasError: false));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool validateType() {
|
||||
final type = state.planData.type;
|
||||
if (type.isEmpty || type.every((elem) => elem)) {
|
||||
emit(state.copyWith.validationState(typeHasError: true));
|
||||
return false;
|
||||
}
|
||||
emit(state.copyWith.validationState(typeHasError: false));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool validateImage() {
|
||||
if (state.planData.image == null) {
|
||||
emit(state.copyWith.validationState(imageHasError: true));
|
||||
return false;
|
||||
}
|
||||
emit(state.copyWith.validationState(imageHasError: false));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool validateSelectedOptionPrice() {
|
||||
final option = state.planData.options[state.selectedOptionIndex ?? 0];
|
||||
final optionsValidationsStates = [...state.validationState.optionsValidationState];
|
||||
if (option.price < 1200) {
|
||||
optionsValidationsStates[state.selectedOptionIndex ?? 0] = optionsValidationsStates[state.selectedOptionIndex ?? 0].copyWith(priceHasError: true);
|
||||
emit(state.copyWith.validationState(optionsValidationState: optionsValidationsStates));
|
||||
return false;
|
||||
}
|
||||
optionsValidationsStates[state.selectedOptionIndex ?? 0] = optionsValidationsStates[state.selectedOptionIndex ?? 0].copyWith(priceHasError: false);
|
||||
emit(state.copyWith.validationState(optionsValidationState: optionsValidationsStates));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool validatePriceOfAllFilledOptions() {
|
||||
final options = state.planData.options;
|
||||
final optionsValidationsStates = [...state.validationState.optionsValidationState];
|
||||
bool result = true;
|
||||
if (options[0].price < 1200) {
|
||||
optionsValidationsStates[0] = optionsValidationsStates[0].copyWith(priceHasError: true);
|
||||
emit(state.copyWith.validationState(optionsValidationState: optionsValidationsStates));
|
||||
result = false;
|
||||
} else {
|
||||
optionsValidationsStates[0] = optionsValidationsStates[0].copyWith(priceHasError: false);
|
||||
emit(state.copyWith.validationState(optionsValidationState: optionsValidationsStates));
|
||||
}
|
||||
|
||||
if (options[1].price < 1200) {
|
||||
optionsValidationsStates[1] = optionsValidationsStates[1].copyWith(priceHasError: true);
|
||||
emit(state.copyWith.validationState(optionsValidationState: optionsValidationsStates));
|
||||
result = false;
|
||||
} else {
|
||||
optionsValidationsStates[1] = optionsValidationsStates[1].copyWith(priceHasError: false);
|
||||
emit(state.copyWith.validationState(optionsValidationState: optionsValidationsStates));
|
||||
}
|
||||
|
||||
if (options[2].price < 1200) {
|
||||
optionsValidationsStates[2] = optionsValidationsStates[2].copyWith(priceHasError: true);
|
||||
emit(state.copyWith.validationState(optionsValidationState: optionsValidationsStates));
|
||||
result = false;
|
||||
} else {
|
||||
optionsValidationsStates[2] = optionsValidationsStates[2].copyWith(priceHasError: false);
|
||||
emit(state.copyWith.validationState(optionsValidationState: optionsValidationsStates));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool validateSelectedOptionItems() {
|
||||
final option = state.planData.options[state.selectedOptionIndex ?? 0];
|
||||
final optionsValidationsStates = [...state.validationState.optionsValidationState];
|
||||
bool result = true;
|
||||
if (option.items.isEmpty) {
|
||||
optionsValidationsStates[state.selectedOptionIndex ?? 0] = optionsValidationsStates[state.selectedOptionIndex ?? 0].copyWith(isItemsEmpty: true);
|
||||
emit(state.copyWith.validationState(optionsValidationState: optionsValidationsStates));
|
||||
return false;
|
||||
}
|
||||
final itemsErrors = Map<int, bool>.from(optionsValidationsStates[state.selectedOptionIndex ?? 0].itemsErrors);
|
||||
optionsValidationsStates[state.selectedOptionIndex ?? 0] = optionsValidationsStates[state.selectedOptionIndex ?? 0].copyWith(isItemsEmpty: false);
|
||||
for (final (index, item) in option.items.indexed) {
|
||||
if (item.length < 3) {
|
||||
itemsErrors[index] = true;
|
||||
result = false;
|
||||
} else {
|
||||
itemsErrors[index] = false;
|
||||
}
|
||||
}
|
||||
optionsValidationsStates[state.selectedOptionIndex ?? 0] = optionsValidationsStates[state.selectedOptionIndex ?? 0].copyWith(itemsErrors: itemsErrors);
|
||||
emit(state.copyWith.validationState(optionsValidationState: optionsValidationsStates));
|
||||
return result;
|
||||
}
|
||||
|
||||
bool validateItemsOfAllFilledOptions() {
|
||||
final options = state.planData.options;
|
||||
final optionsValidationsStates = [...state.validationState.optionsValidationState];
|
||||
bool result = true;
|
||||
|
||||
if (options[0].items.isEmpty) {
|
||||
optionsValidationsStates[0] = optionsValidationsStates[0].copyWith(isItemsEmpty: true);
|
||||
result = false;
|
||||
} else {
|
||||
optionsValidationsStates[0] = optionsValidationsStates[0].copyWith(isItemsEmpty: false);
|
||||
}
|
||||
|
||||
final option1ItemsErrors = Map<int, bool>.from(optionsValidationsStates[0].itemsErrors);
|
||||
for (final (index, item) in options[0].items.indexed) {
|
||||
if (item.length < 3) {
|
||||
option1ItemsErrors[index] = true;
|
||||
result = false;
|
||||
} else {
|
||||
option1ItemsErrors[index] = false;
|
||||
}
|
||||
}
|
||||
|
||||
optionsValidationsStates[0] = optionsValidationsStates[0].copyWith(itemsErrors: option1ItemsErrors);
|
||||
if (state.selectedOptionIndex == null) {
|
||||
emit(state.copyWith.validationState(optionsValidationState: optionsValidationsStates));
|
||||
return result;
|
||||
}
|
||||
if (options[1].items.isEmpty) {
|
||||
optionsValidationsStates[1] = optionsValidationsStates[1].copyWith(isItemsEmpty: true);
|
||||
result = false;
|
||||
} else {
|
||||
optionsValidationsStates[1] = optionsValidationsStates[1].copyWith(isItemsEmpty: false);
|
||||
}
|
||||
|
||||
final option2ItemsErrors = Map<int, bool>.from(optionsValidationsStates[1].itemsErrors);
|
||||
for (final (index, item) in options[1].items.indexed) {
|
||||
if (item.length < 3) {
|
||||
option2ItemsErrors[index] = true;
|
||||
result = false;
|
||||
} else {
|
||||
option2ItemsErrors[index] = false;
|
||||
}
|
||||
}
|
||||
|
||||
optionsValidationsStates[1] = optionsValidationsStates[1].copyWith(itemsErrors: option2ItemsErrors);
|
||||
|
||||
if (options[2].items.isEmpty) {
|
||||
optionsValidationsStates[2] = optionsValidationsStates[2].copyWith(isItemsEmpty: true);
|
||||
result = false;
|
||||
} else {
|
||||
optionsValidationsStates[2] = optionsValidationsStates[2].copyWith(isItemsEmpty: false);
|
||||
}
|
||||
|
||||
final option3ItemsErrors = Map<int, bool>.from(optionsValidationsStates[2].itemsErrors);
|
||||
for (final (index, item) in options[2].items.indexed) {
|
||||
if (item.length < 3) {
|
||||
option3ItemsErrors[index] = true;
|
||||
result = false;
|
||||
} else {
|
||||
option3ItemsErrors[index] = false;
|
||||
}
|
||||
}
|
||||
optionsValidationsStates[2] = optionsValidationsStates[2].copyWith(itemsErrors: option3ItemsErrors);
|
||||
emit(state.copyWith.validationState(optionsValidationState: optionsValidationsStates));
|
||||
return result;
|
||||
}
|
||||
|
||||
bool validateSelectedOptionTitle() {
|
||||
final option = state.planData.options[state.selectedOptionIndex ?? 0];
|
||||
final optionsValidationsStates = [...state.validationState.optionsValidationState];
|
||||
if (option.short.length < 3) {
|
||||
optionsValidationsStates[state.selectedOptionIndex ?? 0] = optionsValidationsStates[state.selectedOptionIndex ?? 0].copyWith(titleHasError: true);
|
||||
emit(state.copyWith.validationState(optionsValidationState: optionsValidationsStates));
|
||||
return false;
|
||||
}
|
||||
optionsValidationsStates[state.selectedOptionIndex ?? 0] = optionsValidationsStates[state.selectedOptionIndex ?? 0].copyWith(titleHasError: false);
|
||||
emit(state.copyWith.validationState(optionsValidationState: optionsValidationsStates));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool validateTitlesOfAllFilledOptions() {
|
||||
final options = state.planData.options;
|
||||
final optionsValidationsStates = [...state.validationState.optionsValidationState];
|
||||
bool result = true;
|
||||
if (options[0].short.length < 3) {
|
||||
optionsValidationsStates[0] = optionsValidationsStates[0].copyWith(titleHasError: true);
|
||||
emit(state.copyWith.validationState(optionsValidationState: optionsValidationsStates));
|
||||
result = false;
|
||||
} else {
|
||||
optionsValidationsStates[0] = optionsValidationsStates[0].copyWith(titleHasError: false);
|
||||
emit(state.copyWith.validationState(optionsValidationState: optionsValidationsStates));
|
||||
}
|
||||
if (state.selectedOptionIndex == null) return result;
|
||||
|
||||
if (options[1].short.length < 3) {
|
||||
optionsValidationsStates[1] = optionsValidationsStates[1].copyWith(titleHasError: true);
|
||||
emit(state.copyWith.validationState(optionsValidationState: optionsValidationsStates));
|
||||
result = false;
|
||||
} else {
|
||||
optionsValidationsStates[1] = optionsValidationsStates[1].copyWith(titleHasError: false);
|
||||
emit(state.copyWith.validationState(optionsValidationState: optionsValidationsStates));
|
||||
}
|
||||
|
||||
if (options[2].short.length < 3) {
|
||||
optionsValidationsStates[2] = optionsValidationsStates[2].copyWith(titleHasError: true);
|
||||
emit(state.copyWith.validationState(optionsValidationState: optionsValidationsStates));
|
||||
result = false;
|
||||
} else {
|
||||
optionsValidationsStates[2] = optionsValidationsStates[2].copyWith(titleHasError: false);
|
||||
emit(state.copyWith.validationState(optionsValidationState: optionsValidationsStates));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool validateSelectedOptionDescription() {
|
||||
final option = state.planData.options[state.selectedOptionIndex ?? 0];
|
||||
final optionsValidationsStates = [...state.validationState.optionsValidationState];
|
||||
if (option.description.length < 3) {
|
||||
optionsValidationsStates[state.selectedOptionIndex ?? 0] = optionsValidationsStates[state.selectedOptionIndex ?? 0].copyWith(descriptionHasError: true);
|
||||
emit(state.copyWith.validationState(optionsValidationState: optionsValidationsStates));
|
||||
return false;
|
||||
}
|
||||
optionsValidationsStates[state.selectedOptionIndex ?? 0] = optionsValidationsStates[state.selectedOptionIndex ?? 0].copyWith(descriptionHasError: false);
|
||||
emit(state.copyWith.validationState(optionsValidationState: optionsValidationsStates));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool validateDescriptionsOfAllOptions() {
|
||||
final options = state.planData.options;
|
||||
final optionsValidationsStates = [...state.validationState.optionsValidationState];
|
||||
bool result = true;
|
||||
|
||||
if (options[0].description.length < 3) {
|
||||
optionsValidationsStates[0] = optionsValidationsStates[0].copyWith(descriptionHasError: true);
|
||||
emit(state.copyWith.validationState(optionsValidationState: optionsValidationsStates));
|
||||
result = false;
|
||||
} else {
|
||||
optionsValidationsStates[0] = optionsValidationsStates[0].copyWith(descriptionHasError: false);
|
||||
emit(state.copyWith.validationState(optionsValidationState: optionsValidationsStates));
|
||||
}
|
||||
if (state.selectedOptionIndex == null) return result;
|
||||
if (options[1].description.length < 3) {
|
||||
optionsValidationsStates[1] = optionsValidationsStates[1].copyWith(descriptionHasError: true);
|
||||
emit(state.copyWith.validationState(optionsValidationState: optionsValidationsStates));
|
||||
result = false;
|
||||
} else {
|
||||
optionsValidationsStates[1] = optionsValidationsStates[1].copyWith(descriptionHasError: false);
|
||||
emit(state.copyWith.validationState(optionsValidationState: optionsValidationsStates));
|
||||
}
|
||||
|
||||
if (options[2].description.length < 3) {
|
||||
optionsValidationsStates[2] = optionsValidationsStates[2].copyWith(descriptionHasError: true);
|
||||
emit(state.copyWith.validationState(optionsValidationState: optionsValidationsStates));
|
||||
result = false;
|
||||
} else {
|
||||
optionsValidationsStates[2] = optionsValidationsStates[2].copyWith(descriptionHasError: false);
|
||||
emit(state.copyWith.validationState(optionsValidationState: optionsValidationsStates));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool validateAllFields() {
|
||||
final isNameValid = validateName();
|
||||
final isDetailsValid = validateDetails();
|
||||
final isImageValid = validateImage();
|
||||
final isDurationValid = validateDuration();
|
||||
final areTitlesValid = validateTitlesOfAllFilledOptions();
|
||||
final arePricesValid = validatePriceOfAllFilledOptions();
|
||||
final areDescriptionsValid = validateDescriptionsOfAllOptions();
|
||||
final areItemsValid = validateItemsOfAllFilledOptions();
|
||||
return isNameValid && isDetailsValid && isImageValid && isDurationValid && areTitlesValid && arePricesValid && areDescriptionsValid && areItemsValid;
|
||||
}
|
||||
|
||||
Future<void> publishPlan() async {
|
||||
if (validateAllFields()) {
|
||||
emit(state.copyWith(isLoading: true));
|
||||
final planModel = await state.planData.toCreationJson();
|
||||
final plan = await createPlanRepository.createPlan(model: planModel);
|
||||
if (state.planData.options[1].short.isNotEmpty) {
|
||||
final options = state.planData.toOptionsCreationJson();
|
||||
await createPlanRepository.createPacketOptions(slug: plan.slug, model: options);
|
||||
} else {
|
||||
final option = state.planData.toOptionCreationJson();
|
||||
await createPlanRepository.createPacketOption(slug: plan.slug, model: option);
|
||||
}
|
||||
emit(state.copyWith(isLoading: false, planCreated: true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,9 @@ class CreatePlanState with _$CreatePlanState {
|
||||
const factory CreatePlanState({
|
||||
required bool isLoading,
|
||||
required String? errorMessage,
|
||||
required CreatePlanModel planData,
|
||||
required CreatePlanModel planData,
|
||||
required PlanValidationState validationState,
|
||||
required bool planCreated,
|
||||
int? durationIndex,
|
||||
int? selectedOptionIndex,
|
||||
}) = _CreatePlanState;
|
||||
@@ -17,9 +19,55 @@ class CreatePlanState with _$CreatePlanState {
|
||||
factory CreatePlanState.initial() => CreatePlanState(
|
||||
isLoading: false,
|
||||
errorMessage: null,
|
||||
planCreated: false,
|
||||
validationState: PlanValidationState.empty(),
|
||||
planData: CreatePlanModel(
|
||||
type: [false, false, false, false],
|
||||
options: [PacketOptions.empty(), PacketOptions.empty(), PacketOptions.empty()],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class PlanValidationState with _$PlanValidationState {
|
||||
factory PlanValidationState({
|
||||
required bool titleHasError,
|
||||
required bool durationHasError,
|
||||
required bool typeHasError,
|
||||
required bool descriptionHasError,
|
||||
required bool imageHasError,
|
||||
required List<OptionValidationState> optionsValidationState,
|
||||
}) = _PlanValidationState;
|
||||
|
||||
factory PlanValidationState.empty() => PlanValidationState(
|
||||
titleHasError: false,
|
||||
durationHasError: false,
|
||||
typeHasError: false,
|
||||
descriptionHasError: false,
|
||||
imageHasError: false,
|
||||
optionsValidationState: [
|
||||
OptionValidationState.empty(),
|
||||
OptionValidationState.empty(),
|
||||
OptionValidationState.empty(),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class OptionValidationState with _$OptionValidationState {
|
||||
factory OptionValidationState({
|
||||
required bool titleHasError,
|
||||
required bool priceHasError,
|
||||
required bool descriptionHasError,
|
||||
required Map<int, bool> itemsErrors,
|
||||
required bool isItemsEmpty,
|
||||
}) = _OptionValidationState;
|
||||
|
||||
factory OptionValidationState.empty() => OptionValidationState(
|
||||
descriptionHasError: false,
|
||||
titleHasError: false,
|
||||
priceHasError: false,
|
||||
isItemsEmpty: false,
|
||||
itemsErrors: {},
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user