feat(recipe): add creating recipes

This commit is contained in:
Alex
2024-12-18 11:56:20 +03:00
parent f6d4ea7df6
commit e0ec45e19e
24 changed files with 2267 additions and 510 deletions

View File

@@ -0,0 +1,121 @@
import 'dart:io';
import 'package:eatvio_app/features/recipes/presentation/bloc/create_recipe_cubit/create_recipe_cubit.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:image_picker/image_picker.dart';
class ImageWidget extends StatefulWidget {
const ImageWidget({super.key});
@override
State<ImageWidget> createState() => _ImageWidgetState();
}
class _ImageWidgetState extends State<ImageWidget> {
XFile? image;
late final CreateRecipeCubit createRecipeCubit;
@override
void initState() {
super.initState();
createRecipeCubit = context.read<CreateRecipeCubit>();
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
_showImagePicker();
},
child: image == null
? SvgPicture.asset(
width: MediaQuery.of(context).size.width - 32,
'assets/icons/upload_photo_of_portion.svg',
)
: Stack(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Image.file(
File(image!.path),
),
),
Positioned(
right: 16,
top: 16,
child: GestureDetector(
onTap: () {
setState(() {
image = null;
});
createRecipeCubit.replaceImage(null);
},
child: Container(
padding: EdgeInsets.all(4),
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
),
child: Icon(Icons.close_rounded),
),
),
),
],
),
);
}
_showImagePicker() {
showCupertinoModalPopup<void>(
context: context,
builder: (context) => CupertinoActionSheet(
actions: [
CupertinoActionSheetAction(
onPressed: () async {
final picker = ImagePicker();
image = await picker.pickImage(source: ImageSource.camera);
setState(() {});
if (image != null) {
createRecipeCubit.replaceImage(File(image!.path));
}
Navigator.of(context).pop();
},
child: const Row(
children: const [
Icon(Icons.photo_camera),
SizedBox(width: 8),
Text('Фото'),
],
),
),
CupertinoActionSheetAction(
onPressed: () async {
final picker = ImagePicker();
image = await picker.pickImage(source: ImageSource.gallery);
setState(() {});
if (image != null) {
createRecipeCubit.replaceImage(File(image!.path));
}
Navigator.of(context).pop();
},
child: const Row(
children: const [
Icon(Icons.photo),
SizedBox(width: 8),
Text('Галерея'),
],
),
),
],
cancelButton: CupertinoActionSheetAction(
onPressed: () => Navigator.of(context).pop(),
isDestructiveAction: true,
child: const Text('Отмена'),
),
),
);
}
}

View File

@@ -0,0 +1,113 @@
import 'package:eatvio_app/core/data/selectionPopupModel/selection_popup_model.dart';
import 'package:eatvio_app/core/widgets/custom_drop_down.dart';
import 'package:eatvio_app/core/widgets/custom_text_form_field.dart';
import 'package:eatvio_app/features/recipes/entities/recipe_create_entity.dart';
import 'package:eatvio_app/features/recipes/presentation/bloc/create_recipe_cubit/create_recipe_cubit.dart';
import 'package:eatvio_app/features/recipes/presentation/widgets/image_widget.dart';
import 'package:eatvio_app/features/recipes/presentation/widgets/portion_widget.dart';
import 'package:eatvio_app/features/recipes/presentation/widgets/tags_widget.dart';
import 'package:eatvio_app/features/recipes/presentation/widgets/time_of_cook_widget.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class InfoAboutRecipeWidget extends StatefulWidget {
const InfoAboutRecipeWidget({super.key});
@override
State<InfoAboutRecipeWidget> createState() => _InfoAboutRecipeWidgetState();
}
class _InfoAboutRecipeWidgetState extends State<InfoAboutRecipeWidget> {
final List<SelectionPopupModel> items = const [
SelectionPopupModel(title: 'Первые Блюда'),
SelectionPopupModel(title: 'Вторые Блюда'),
SelectionPopupModel(title: 'Салаты'),
SelectionPopupModel(title: 'Сладости'),
SelectionPopupModel(title: 'Напитки'),
SelectionPopupModel(title: 'Прочее'),
];
late SelectionPopupModel selectedType;
late final CreateRecipeCubit createRecipeCubit;
@override
void initState() {
super.initState();
selectedType = items.first;
createRecipeCubit = context.read<CreateRecipeCubit>();
}
@override
Widget build(BuildContext context) {
return Material(
borderRadius: BorderRadius.circular(12),
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Название'),
SizedBox(height: 4),
CustomTextFormField(
hintText: 'Например: тар-тар из говядины',
onChanged: (value) {
createRecipeCubit.replaceTitle(value);
},
),
const SizedBox(height: 12),
Text('Тип блюда'),
SizedBox(height: 4),
CustomDropDown(
items: items,
value: selectedType,
onChanged: (newSelectedType) {
setState(() {
selectedType = newSelectedType;
});
createRecipeCubit.changeType(
switch (selectedType.title) {
'Первые Блюда' => TypeOfRecipe.first_meals,
'Вторые Блюда' => TypeOfRecipe.second_meals,
'Салаты' => TypeOfRecipe.salads,
'Сладости' => TypeOfRecipe.sweets,
'Напитки' => TypeOfRecipe.drinks,
_ => TypeOfRecipe.other,
},
);
},
),
const SizedBox(height: 12),
TagsWidget(),
const SizedBox(height: 12),
PortionWidget(),
const SizedBox(height: 12),
TimeOfCookWidget(),
const SizedBox(height: 12),
Text('Описание'),
SizedBox(height: 4),
CustomTextFormField(
hintText: 'Расскажите, почему вы выбрали именно этот рецепт? Опишите, каким будет готовое блюдо и в чём его достоинства.',
minLines: 5,
maxLines: 5,
onChanged: (value) {
createRecipeCubit.replaceDescription(value);
},
),
const SizedBox(height: 12),
Text('Фото обложка'),
SizedBox(height: 4),
ImageWidget(),
const SizedBox(height: 12),
Text('Ссылка на видео (если есть)'),
SizedBox(height: 4),
CustomTextFormField(
hintText: 'Прикрепите ссылку на видео',
onChanged: (value) {
createRecipeCubit.replaceVideoUrl(value);
},
),
],
),
),
);
}
}

View File

@@ -0,0 +1,219 @@
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/recipes/entities/recipe_create_entity.dart';
import 'package:eatvio_app/features/recipes/presentation/bloc/create_recipe_cubit/create_recipe_cubit.dart';
import 'package:eatvio_app/features/recipes/presentation/bloc/create_recipe_cubit/create_recipe_state.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class IngredientsWidget extends StatefulWidget {
const IngredientsWidget({super.key});
@override
State<IngredientsWidget> createState() => _IngredientsWidgetState();
}
class _IngredientsWidgetState extends State<IngredientsWidget> {
late final CreateRecipeCubit createRecipeCubit;
@override
void initState() {
super.initState();
createRecipeCubit = context.read<CreateRecipeCubit>();
}
@override
Widget build(BuildContext context) {
return BlocBuilder<CreateRecipeCubit, CreateRecipeState>(
builder: (BuildContext context, CreateRecipeState state) {
return Material(
borderRadius: BorderRadius.circular(12),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 16),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Text(
'Ингредиенты ',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w600,
color: Color(0xFF323F4B),
),
),
),
ReorderableListView(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
onReorder: (int oldIndex, int newIndex) {
setState(() {
if (oldIndex < newIndex) {
newIndex -= 1;
}
});
createRecipeCubit.replaceIngredientPosition(oldIndex, newIndex);
},
children: <Widget>[
for (int index = 0; index < state.entity.ingredients.length; index += 1)
ListTile(
contentPadding: EdgeInsets.symmetric(horizontal: 16),
key: Key('$index'),
leading: Icon(
Icons.drag_handle_rounded,
color: Colors.grey.shade600,
),
title: Text(state.entity.ingredients[index].name),
subtitle: Text('${state.entity.ingredients[index].unit} ${state.entity.ingredients[index].portion == 'gr' ? 'гр' : 'шт'}'),
trailing: IconButton(
onPressed: () {
createRecipeCubit.removeIngredient(index);
},
icon: Icon(
Icons.delete_outline_rounded,
color: Colors.grey.shade600,
),
),
),
],
),
ListTile(
onTap: () => showModalBottomSheet(
useRootNavigator: true,
context: context,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(12)),
),
isScrollControlled: true,
builder: (context) {
final nameController = TextEditingController();
final grammsContorller = TextEditingController();
final pcsController = TextEditingController();
return StatefulBuilder(
builder: (BuildContext context, void Function(void Function()) setStateInner) {
return Padding(
padding: const EdgeInsets.all(16) +
EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
'Добавление ингредиента',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w600,
color: Color(0xFF323F4B),
),
),
const SizedBox(height: 16),
SizedBox(
width: MediaQuery.of(context).size.width - 32,
child: CustomTextFormField(
autofocus: true,
controller: nameController,
hintText: 'Введите название продукта',
onChanged: (query) {},
),
),
const SizedBox(height: 8),
Row(
children: [
SizedBox(
width: MediaQuery.of(context).size.width / 2 - 20,
child: CustomTextFormField(
enabled: pcsController.text.isEmpty ? true : false,
keyboardType: TextInputType.number,
controller: grammsContorller,
hintText: pcsController.text.isEmpty ? '100' : null,
suffixText: 'гр',
onChanged: (value) {
setStateInner(() {});
},
),
),
const SizedBox(width: 8),
SizedBox(
width: MediaQuery.of(context).size.width / 2 - 20,
child: CustomTextFormField(
enabled: grammsContorller.text.isEmpty ? true : false,
keyboardType: TextInputType.number,
controller: pcsController,
onChanged: (value) {
setStateInner(() {});
},
hintText: grammsContorller.text.isEmpty ? '1' : null,
suffixText: 'шт',
),
),
],
),
const SizedBox(height: 12),
InkWell(
onTap: () {
if (nameController.text.isNotEmpty && (pcsController.text.isNotEmpty || grammsContorller.text.isNotEmpty)) {
createRecipeCubit.addIngredient(
IngredientEntity(
name: nameController.text,
unit: grammsContorller.text.isEmpty ? pcsController.text : grammsContorller.text,
portion: grammsContorller.text.isEmpty ? 'pcs' : 'gr',
),
);
Navigator.of(context).pop();
setState(() {});
}
},
borderRadius: BorderRadius.circular(20),
child: Ink(
width: MediaQuery.of(context).size.width - 32,
height: 52,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: appTheme.blueA400,
),
child: Center(
child: Text(
'Добавить',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
color: Colors.white,
),
),
),
),
),
],
),
);
},
);
},
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
title: Text(
'Добавить ингредиент',
style: TextStyle(
color: appTheme.blueA400,
),
),
leading: Icon(
Icons.add_rounded,
color: appTheme.blueA400,
),
),
],
),
),
);
},
);
}
}

View File

@@ -0,0 +1,69 @@
import 'package:eatvio_app/core/widgets/custom_text_form_field.dart';
import 'package:eatvio_app/features/recipes/presentation/bloc/create_recipe_cubit/create_recipe_cubit.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class PortionWidget extends StatefulWidget {
const PortionWidget({super.key});
@override
State<PortionWidget> createState() => _PortionWidgetState();
}
class _PortionWidgetState extends State<PortionWidget> {
late final CreateRecipeCubit createRecipeCubit;
@override
void initState() {
super.initState();
createRecipeCubit = context.read<CreateRecipeCubit>();
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Кол-во порций'),
SizedBox(height: 4),
CustomTextFormField(
hintText: '1',
onChanged: (value) {
createRecipeCubit.replacePortionsCount(int.parse(value));
},
),
],
),
),
const SizedBox(width: 8),
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Ккал в одной порции'),
SizedBox(height: 4),
CustomTextFormField(
hintText: '100',
suffixText: 'Ккал',
onChanged: (value) {
createRecipeCubit.replaceEnegryInPortion(double.parse(value));
},
),
],
),
),
],
),
],
);
}
}

View File

@@ -0,0 +1,126 @@
import 'dart:io';
import 'package:eatvio_app/features/recipes/presentation/bloc/create_recipe_cubit/create_recipe_cubit.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:image_picker/image_picker.dart';
class StepImageWidget extends StatefulWidget {
final int index;
const StepImageWidget({
super.key,
required this.index,
});
@override
State<StepImageWidget> createState() => _StepImageWidgetState();
}
class _StepImageWidgetState extends State<StepImageWidget> {
XFile? image;
late final CreateRecipeCubit createRecipeCubit;
@override
void initState() {
super.initState();
createRecipeCubit = context.read<CreateRecipeCubit>();
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
_showImagePicker();
},
child: image == null
? SvgPicture.asset(
width: MediaQuery.of(context).size.width - 32,
'assets/icons/add_step_photo.svg',
)
: Stack(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Image.file(
File(image!.path),
),
),
Positioned(
right: 16,
top: 16,
child: GestureDetector(
onTap: () {
setState(() {
image = null;
});
createRecipeCubit.replaceImageInStep(null, widget.index);
},
child: Container(
padding: EdgeInsets.all(4),
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
),
child: Icon(Icons.close_rounded),
),
),
),
],
),
);
}
_showImagePicker() {
showCupertinoModalPopup<void>(
context: context,
builder: (context) => CupertinoActionSheet(
actions: [
CupertinoActionSheetAction(
onPressed: () async {
final picker = ImagePicker();
image = await picker.pickImage(source: ImageSource.camera);
setState(() {});
if (image != null) {
createRecipeCubit.replaceImageInStep(File(image!.path), widget.index);
}
Navigator.of(context).pop();
},
child: const Row(
children: const [
Icon(Icons.photo_camera),
SizedBox(width: 8),
Text('Фото'),
],
),
),
CupertinoActionSheetAction(
onPressed: () async {
final picker = ImagePicker();
image = await picker.pickImage(source: ImageSource.gallery);
setState(() {});
if (image != null) {
createRecipeCubit.replaceImageInStep(File(image!.path), widget.index);
}
Navigator.of(context).pop();
},
child: const Row(
children: const [
Icon(Icons.photo),
SizedBox(width: 8),
Text('Галерея'),
],
),
),
],
cancelButton: CupertinoActionSheetAction(
onPressed: () => Navigator.of(context).pop(),
isDestructiveAction: true,
child: const Text('Отмена'),
),
),
);
}
}

View File

@@ -0,0 +1,135 @@
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/recipes/presentation/bloc/create_recipe_cubit/create_recipe_cubit.dart';
import 'package:eatvio_app/features/recipes/presentation/bloc/create_recipe_cubit/create_recipe_state.dart';
import 'package:eatvio_app/features/recipes/presentation/widgets/step_image_widget.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class StepsWidget extends StatefulWidget {
const StepsWidget({super.key});
@override
State<StepsWidget> createState() => _StepsWidgetState();
}
class _StepsWidgetState extends State<StepsWidget> {
late final CreateRecipeCubit createRecipeCubit;
@override
void initState() {
super.initState();
createRecipeCubit = context.read<CreateRecipeCubit>();
}
@override
Widget build(BuildContext context) {
return BlocBuilder<CreateRecipeCubit, CreateRecipeState>(
builder: (BuildContext context, CreateRecipeState state) {
return Material(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Пошаговая инструкция',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w600,
color: Color(0xFF323F4B),
),
),
const SizedBox(height: 12),
ListView.separated(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) => Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
padding: EdgeInsets.symmetric(
horizontal: 12,
vertical: 4,
),
decoration: BoxDecoration(
color: appTheme.blueA400,
borderRadius: BorderRadius.circular(8),
),
child: Text(
'Шаг ${index + 1}',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w600,
),
),
),
GestureDetector(
onTap: () {
context.read<CreateRecipeCubit>().removeStep(state.entity.steps[index]);
},
child: Icon(Icons.delete_outline_rounded),
),
],
),
const SizedBox(height: 12),
Text('Описание'),
SizedBox(height: 4),
CustomTextFormField(
hintText: 'Например: подготовьте ингредиенты',
maxLines: 5,
minLines: 3,
onChanged: (value) {
createRecipeCubit.replaceDescriptionInStep(value, index);
},
),
const SizedBox(height: 12),
Text('Фото шага'),
SizedBox(height: 4),
StepImageWidget(
index: index,
),
],
),
itemCount: state.entity.steps.length,
separatorBuilder: (BuildContext context, int index) => const SizedBox(height: 24),
),
InkWell(
onTap: () {
context.read<CreateRecipeCubit>().addStep();
},
borderRadius: BorderRadius.circular(20),
child: Ink(
width: MediaQuery.of(context).size.width - 32,
decoration: BoxDecoration(
color: appTheme.blueA400,
borderRadius: BorderRadius.circular(20),
),
child: Container(
padding: const EdgeInsets.all(16),
alignment: Alignment.center,
child: Text(
'Добавить шаг',
style: TextStyle(
fontSize: 16,
color: Colors.white,
fontWeight: FontWeight.w600,
),
),
),
),
),
],
),
),
);
},
);
}
}

View File

@@ -0,0 +1,82 @@
import 'package:eatvio_app/core/theme/theme_helper.dart';
import 'package:eatvio_app/core/widgets/custom_text_form_field.dart';
import 'package:flutter/material.dart';
class TagsWidget extends StatefulWidget {
const TagsWidget({super.key});
@override
State<TagsWidget> createState() => _TagsWidgetState();
}
class _TagsWidgetState extends State<TagsWidget> {
final tagController = TextEditingController();
final List<String> tags = [];
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Теги'),
SizedBox(height: 4),
CustomTextFormField(
hintText: 'Например: без майонеза',
controller: tagController,
suffix: IconButton(
onPressed: () {
if (tagController.text.isNotEmpty) {
setState(() {
tags.add(tagController.text);
tagController.clear();
});
}
},
icon: Icon(
Icons.done,
color: appTheme.blueA400,
),
),
),
const SizedBox(height: 12),
Wrap(
spacing: 8,
runSpacing: 8,
children: [
for (int i = 0; i < tags.length; i++) ...[
InkWell(
onTap: () {
setState(() {
tags.remove(tags[i]);
});
},
borderRadius: BorderRadius.circular(16),
child: Ink(
padding: EdgeInsets.symmetric(vertical: 4, horizontal: 12),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
color: Colors.grey.shade200,
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
tags[i],
),
const SizedBox(width: 4),
Icon(
Icons.delete_outline_rounded,
color: Colors.grey.shade600,
size: 20,
),
],
),
),
),
],
],
),
],
);
}
}

View File

@@ -0,0 +1,151 @@
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/recipes/presentation/bloc/create_recipe_cubit/create_recipe_cubit.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class TimeOfCookWidget extends StatefulWidget {
const TimeOfCookWidget({super.key});
@override
State<TimeOfCookWidget> createState() => _TimeOfCookWidgetState();
}
class _TimeOfCookWidgetState extends State<TimeOfCookWidget> {
late final CreateRecipeCubit createRecipeCubit;
@override
void initState() {
super.initState();
createRecipeCubit = context.read<CreateRecipeCubit>();
}
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: [
Text('Общее время приготовления'),
const SizedBox(width: 8),
GestureDetector(
onTap: () {
showDialog(
context: context,
builder: (context) => AlertDialog(
content: Text(
'Общее время приготовления - это период времени от начала приготовления блюда до подачи его на стол.',
style: TextStyle(
fontWeight: FontWeight.w500,
color: Color(0xFF323F4B),
height: 1.2,
),
),
),
);
},
child: Icon(
Icons.help_outline_rounded,
color: appTheme.blueA400,
size: 20,
),
),
],
),
SizedBox(height: 4),
Row(
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
child: CustomTextFormField(
hintText: 'Часов',
onChanged: (value) {
if (createRecipeCubit.state.entity.totalCookTime == null) {
createRecipeCubit.replaceTotalTime('${value.padLeft(2, '0')}:00');
} else {
createRecipeCubit.replaceTotalTime('${value.padLeft(2, '0')}:${createRecipeCubit.state.entity.totalCookTime!.substring(3, 5)}');
}
},
),
),
const SizedBox(width: 8),
Expanded(
child: CustomTextFormField(
hintText: 'Минут',
onChanged: (value) {
if (createRecipeCubit.state.entity.totalCookTime == null) {
createRecipeCubit.replaceTotalTime('00:${value.padLeft(2, '0')}');
} else {
createRecipeCubit.replaceTotalTime('${createRecipeCubit.state.entity.totalCookTime!.substring(0, 2)}:${value.padLeft(2, '0')}');
}
},
),
),
],
),
const SizedBox(height: 12),
Row(
children: [
Text('Активное время приготовления'),
const SizedBox(width: 8),
GestureDetector(
onTap: () {
showDialog(
context: context,
builder: (context) => AlertDialog(
content: Text(
'Активное время приготовления - это период времени, требующий активного участия в приготовлении блюда. Оно включает мытье и очистку продуктов, нарезку, шинковку, взбивание, перемешивание, размешивание, перекладывание и т.п.',
style: TextStyle(
fontWeight: FontWeight.w500,
color: Color(0xFF323F4B),
height: 1.2,
),
),
),
);
},
child: Icon(
Icons.help_outline_rounded,
color: appTheme.blueA400,
size: 20,
),
),
],
),
SizedBox(height: 4),
Row(
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
child: CustomTextFormField(
hintText: 'Часов',
onChanged: (value) {
if (createRecipeCubit.state.entity.activeCookTime == null) {
createRecipeCubit.replaceActiveTime('${value.padLeft(2, '0')}:00');
} else {
createRecipeCubit.replaceActiveTime('${value.padLeft(2, '0')}:${createRecipeCubit.state.entity.activeCookTime!.substring(3, 5)}');
}
},
),
),
const SizedBox(width: 8),
Expanded(
child: CustomTextFormField(
hintText: 'Минут',
onChanged: (value) {
if (createRecipeCubit.state.entity.activeCookTime == null) {
createRecipeCubit.replaceActiveTime('00:${value.padLeft(2, '0')}');
} else {
createRecipeCubit.replaceActiveTime('${createRecipeCubit.state.entity.activeCookTime!.substring(0, 2)}:${value.padLeft(2, '0')}');
}
},
),
),
],
),
],
);
}
}