added page(s) to create a recipe
This commit is contained in:
parent
c9c4798e87
commit
de9e5f8ba6
5 changed files with 432 additions and 24 deletions
|
@ -8,6 +8,8 @@ import 'package:pizzaplanner/entities/PizzaRecipe/recipe_step.dart';
|
||||||
import 'package:pizzaplanner/entities/PizzaRecipe/recipe_substep.dart';
|
import 'package:pizzaplanner/entities/PizzaRecipe/recipe_substep.dart';
|
||||||
import 'package:pizzaplanner/pages/add_pizza_event_page.dart';
|
import 'package:pizzaplanner/pages/add_pizza_event_page.dart';
|
||||||
import 'package:pizzaplanner/pages/add_recipe_page.dart';
|
import 'package:pizzaplanner/pages/add_recipe_page.dart';
|
||||||
|
import 'package:pizzaplanner/pages/edit_recipe_step_page.dart';
|
||||||
|
import 'package:pizzaplanner/pages/edit_recipe_sub_step_page.dart';
|
||||||
import 'package:pizzaplanner/pages/pick_pizza_recipe_page.dart';
|
import 'package:pizzaplanner/pages/pick_pizza_recipe_page.dart';
|
||||||
import 'package:pizzaplanner/pages/pizza_event_notification_page.dart';
|
import 'package:pizzaplanner/pages/pizza_event_notification_page.dart';
|
||||||
import 'package:pizzaplanner/pages/pizza_event_page.dart';
|
import 'package:pizzaplanner/pages/pizza_event_page.dart';
|
||||||
|
@ -171,6 +173,20 @@ class RouteGenerator {
|
||||||
case "/recipes/add": {
|
case "/recipes/add": {
|
||||||
return MaterialPageRoute(builder: (context) => AddRecipePage());
|
return MaterialPageRoute(builder: (context) => AddRecipePage());
|
||||||
}
|
}
|
||||||
|
case "/recipes/add/edit_step": {
|
||||||
|
final recipeStep = settings.arguments as RecipeStep?;
|
||||||
|
if(recipeStep == null){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return MaterialPageRoute(builder: (context) => EditRecipeStepPage(recipeStep));
|
||||||
|
}
|
||||||
|
case "/recipes/add/edit_sub_step": {
|
||||||
|
final subStep = settings.arguments as RecipeSubStep?;
|
||||||
|
if(subStep == null){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return MaterialPageRoute(builder: (context) => EditRecipeSubStepPage(subStep));
|
||||||
|
}
|
||||||
default: {
|
default: {
|
||||||
return MaterialPageRoute(builder: (context) => PizzaEventsPage());
|
return MaterialPageRoute(builder: (context) => PizzaEventsPage());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||||
|
import 'package:hive/hive.dart';
|
||||||
import 'package:pizzaplanner/entities/PizzaRecipe/ingredient.dart';
|
import 'package:pizzaplanner/entities/PizzaRecipe/ingredient.dart';
|
||||||
import 'package:pizzaplanner/entities/PizzaRecipe/pizza_recipe.dart';
|
import 'package:pizzaplanner/entities/PizzaRecipe/pizza_recipe.dart';
|
||||||
import 'package:pizzaplanner/entities/PizzaRecipe/recipe_step.dart';
|
import 'package:pizzaplanner/entities/PizzaRecipe/recipe_step.dart';
|
||||||
|
import 'package:pizzaplanner/entities/PizzaRecipe/recipe_substep.dart';
|
||||||
import 'package:pizzaplanner/pages/scaffold.dart';
|
import 'package:pizzaplanner/pages/scaffold.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
|
@ -18,32 +20,43 @@ class AddRecipePage extends StatefulWidget {
|
||||||
class AddRecipePageState extends State<AddRecipePage> {
|
class AddRecipePageState extends State<AddRecipePage> {
|
||||||
late PizzaRecipe pizzaRecipe;
|
late PizzaRecipe pizzaRecipe;
|
||||||
|
|
||||||
AddRecipePageState(){
|
bool nameValidation = false;
|
||||||
|
bool descriptionValidation = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
if (widget.pizzaRecipe == null){
|
if (widget.pizzaRecipe == null){
|
||||||
pizzaRecipe = PizzaRecipe(
|
pizzaRecipe = PizzaRecipe(
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
<Ingredient>[],
|
<Ingredient>[
|
||||||
<RecipeStep>[],
|
Ingredient("Flour", "g", 1.0)
|
||||||
|
],
|
||||||
|
<RecipeStep>[
|
||||||
|
RecipeStep("Step 1", "", "", "", 0, 1, <RecipeSubStep>[])
|
||||||
|
],
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
pizzaRecipe = widget.pizzaRecipe!;
|
pizzaRecipe = widget.pizzaRecipe!;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nameValidation = false;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context){
|
Widget build(BuildContext context){
|
||||||
return PizzaPlannerScaffold(
|
return PizzaPlannerScaffold(
|
||||||
title: const Text("Add Recipe"),
|
title: const Text("Add Recipe"),
|
||||||
|
resizeToAvoidBottomInset: true,
|
||||||
body: ListView(
|
body: ListView(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
TextField(
|
TextFormField(
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: "Recipe Name",
|
hintText: "Recipe Name",
|
||||||
errorText: nameValidation ? """Name can't be empty""" : null
|
errorText: nameValidation ? """Name can't be empty""" : null
|
||||||
),
|
),
|
||||||
|
initialValue: widget.pizzaRecipe?.name,
|
||||||
onChanged: (String newName) {
|
onChanged: (String newName) {
|
||||||
setState(() {
|
setState(() {
|
||||||
pizzaRecipe.name = newName;
|
pizzaRecipe.name = newName;
|
||||||
|
@ -51,11 +64,12 @@ class AddRecipePageState extends State<AddRecipePage> {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
TextField(
|
TextFormField(
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: "Recipe Description",
|
hintText: "Recipe Description",
|
||||||
errorText: nameValidation ? """Description can't be empty""" : null
|
errorText: descriptionValidation ? """Description can't be empty""" : null
|
||||||
),
|
),
|
||||||
|
initialValue: widget.pizzaRecipe?.description,
|
||||||
maxLines: 8,
|
maxLines: 8,
|
||||||
onChanged: (String newDescription) {
|
onChanged: (String newDescription) {
|
||||||
setState(() {
|
setState(() {
|
||||||
|
@ -105,7 +119,6 @@ class AddRecipePageState extends State<AddRecipePage> {
|
||||||
const Divider(),
|
const Divider(),
|
||||||
const Center(
|
const Center(
|
||||||
child: Text("Ingredients")
|
child: Text("Ingredients")
|
||||||
|
|
||||||
),
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
Container(
|
Container(
|
||||||
|
@ -114,11 +127,7 @@ class AddRecipePageState extends State<AddRecipePage> {
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
pizzaRecipe.ingredients.add(
|
pizzaRecipe.ingredients.add(
|
||||||
Ingredient(
|
Ingredient("", "", 0.0)
|
||||||
"",
|
|
||||||
"",
|
|
||||||
0.0
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -127,7 +136,41 @@ class AddRecipePageState extends State<AddRecipePage> {
|
||||||
),
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
] + pizzaRecipe.ingredients.map((ingredient) => buildIngredientRow(ingredient)).toList() + [
|
] + pizzaRecipe.ingredients.map((ingredient) => buildIngredientRow(ingredient)).toList() + [
|
||||||
|
const Divider(),
|
||||||
|
const Center(
|
||||||
|
child: Text("Steps")
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
color: Colors.blue,
|
||||||
|
child: TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
pizzaRecipe.recipeSteps.add(
|
||||||
|
RecipeStep("Step ${pizzaRecipe.recipeSteps.length+1}", "", "", "minutes", 0, 1, <RecipeSubStep>[])
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: const Text("Add Step", style: TextStyle(color: Colors.white)),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
const Divider()
|
||||||
|
] + pizzaRecipe.recipeSteps.map((recipeStep) => buildRecipeStepRow(recipeStep)).toList() + [
|
||||||
|
const Divider(),
|
||||||
|
Container(
|
||||||
|
color: Colors.blue,
|
||||||
|
width: double.infinity,
|
||||||
|
child: TextButton(
|
||||||
|
onPressed: () async {
|
||||||
|
if (pizzaRecipe.isInBox){
|
||||||
|
pizzaRecipe.save();
|
||||||
|
} else {
|
||||||
|
final pizzaRecipesBox = await Hive.openBox<PizzaRecipe>("PizzaRecipes");
|
||||||
|
pizzaRecipesBox.add(pizzaRecipe);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: const Text("Save", style: TextStyle(color: Colors.white)),
|
||||||
|
)
|
||||||
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -137,12 +180,12 @@ class AddRecipePageState extends State<AddRecipePage> {
|
||||||
return Row(
|
return Row(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 4,
|
flex: 8,
|
||||||
child: TextField(
|
child: TextFormField(
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
hintText: "Name",
|
hintText: "Name",
|
||||||
),
|
),
|
||||||
controller: TextEditingController(text: ingredient.name),
|
initialValue: ingredient.name,
|
||||||
onChanged: (String newName) {
|
onChanged: (String newName) {
|
||||||
setState(() {
|
setState(() {
|
||||||
ingredient.name = newName;
|
ingredient.name = newName;
|
||||||
|
@ -151,13 +194,13 @@ class AddRecipePageState extends State<AddRecipePage> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 2,
|
flex: 4,
|
||||||
child: TextField(
|
child: TextFormField(
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
hintText: "Value",
|
hintText: "Value",
|
||||||
),
|
),
|
||||||
keyboardType: TextInputType.number,
|
keyboardType: TextInputType.number,
|
||||||
controller: TextEditingController(text: ingredient.value.toString()),
|
initialValue: ingredient.value.toString(),
|
||||||
onChanged: (String newValue) {
|
onChanged: (String newValue) {
|
||||||
setState(() {
|
setState(() {
|
||||||
final newDouble = double.tryParse(newValue);
|
final newDouble = double.tryParse(newValue);
|
||||||
|
@ -171,11 +214,11 @@ class AddRecipePageState extends State<AddRecipePage> {
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 2,
|
flex: 2,
|
||||||
child: TextField(
|
child: TextFormField(
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
hintText: "Unit",
|
hintText: "Unit",
|
||||||
),
|
),
|
||||||
controller: TextEditingController(text: ingredient.unit),
|
initialValue: ingredient.unit,
|
||||||
onChanged: (String newUnit) {
|
onChanged: (String newUnit) {
|
||||||
setState(() {
|
setState(() {
|
||||||
ingredient.unit = newUnit;
|
ingredient.unit = newUnit;
|
||||||
|
@ -196,6 +239,44 @@ class AddRecipePageState extends State<AddRecipePage> {
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget buildRecipeStepRow(RecipeStep recipeStep){
|
||||||
|
return Row(
|
||||||
|
children: <Widget>[
|
||||||
|
Expanded(
|
||||||
|
flex: 10,
|
||||||
|
child: Text(recipeStep.name)
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
flex: 4,
|
||||||
|
child: Container(
|
||||||
|
color: Colors.blue,
|
||||||
|
child: TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
FocusScope.of(context).unfocus();
|
||||||
|
Navigator.pushNamed(context, "/recipes/add/edit_step", arguments: recipeStep).then(
|
||||||
|
(_) {
|
||||||
|
setState((){});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: const Text("Edit", style: TextStyle(color: Colors.white)),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
pizzaRecipe.recipeSteps.remove(recipeStep);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: const Text("X", style: TextStyle(color: Colors.red)),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PreviewMarkdownDescription extends StatelessWidget {
|
class PreviewMarkdownDescription extends StatelessWidget {
|
||||||
|
|
215
lib/pages/edit_recipe_step_page.dart
Normal file
215
lib/pages/edit_recipe_step_page.dart
Normal file
|
@ -0,0 +1,215 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:pizzaplanner/entities/PizzaRecipe/pizza_recipe.dart';
|
||||||
|
import 'package:pizzaplanner/entities/PizzaRecipe/recipe_step.dart';
|
||||||
|
import 'package:pizzaplanner/entities/PizzaRecipe/recipe_substep.dart';
|
||||||
|
import 'package:pizzaplanner/pages/add_recipe_page.dart';
|
||||||
|
import 'package:pizzaplanner/pages/nav_drawer.dart';
|
||||||
|
import 'package:pizzaplanner/pages/scaffold.dart';
|
||||||
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
|
class EditRecipeStepPage extends StatefulWidget {
|
||||||
|
final RecipeStep recipeStep;
|
||||||
|
|
||||||
|
const EditRecipeStepPage(this.recipeStep);
|
||||||
|
|
||||||
|
@override
|
||||||
|
EditRecipeStepPageState createState() => EditRecipeStepPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class EditRecipeStepPageState extends State<EditRecipeStepPage> {
|
||||||
|
|
||||||
|
bool nameValidation = false;
|
||||||
|
bool descriptionValidation = false;
|
||||||
|
|
||||||
|
final waitUnits = ["minutes", "hours","days"].map<DropdownMenuItem<String>>((String unit) =>
|
||||||
|
DropdownMenuItem<String>(
|
||||||
|
value: unit,
|
||||||
|
child: Text(unit)
|
||||||
|
)
|
||||||
|
).toList();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context){
|
||||||
|
return PizzaPlannerScaffold(
|
||||||
|
title: Text("Edit: ${widget.recipeStep.name}"),
|
||||||
|
body: ListView(
|
||||||
|
children: <Widget>[
|
||||||
|
TextFormField(
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: "Recipe Name",
|
||||||
|
errorText: nameValidation ? """Name can't be empty""" : null
|
||||||
|
),
|
||||||
|
initialValue: widget.recipeStep.name,
|
||||||
|
onChanged: (String newName) {
|
||||||
|
setState(() {
|
||||||
|
widget.recipeStep.name = newName;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const Divider(),
|
||||||
|
TextFormField(
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: "Recipe Description",
|
||||||
|
errorText: descriptionValidation ? """Description can't be empty""" : null
|
||||||
|
),
|
||||||
|
initialValue: widget.recipeStep.description,
|
||||||
|
maxLines: 8,
|
||||||
|
onChanged: (String newDescription) {
|
||||||
|
setState(() {
|
||||||
|
widget.recipeStep.description = newDescription;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const Divider(),
|
||||||
|
Row(
|
||||||
|
children: <Widget>[
|
||||||
|
Expanded(
|
||||||
|
flex: 2,
|
||||||
|
child: Container(
|
||||||
|
color: Colors.blue,
|
||||||
|
width: double.infinity,
|
||||||
|
child: TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return PreviewMarkdownDescription(widget.recipeStep.description);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: const Text("Preview", style: TextStyle(color: Colors.white)),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
const Expanded(
|
||||||
|
child: SizedBox()
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
flex: 2,
|
||||||
|
child: Container(
|
||||||
|
color: Colors.blue,
|
||||||
|
width: double.infinity,
|
||||||
|
child: TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
launch("https://guides.github.com/features/mastering-markdown/");
|
||||||
|
},
|
||||||
|
child: const Text("Markdown?", style: TextStyle(color: Colors.white)),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const Divider(),
|
||||||
|
const Center(child: Text("Next step after:")),
|
||||||
|
Row(
|
||||||
|
children: <Widget>[
|
||||||
|
Expanded(
|
||||||
|
flex: 2,
|
||||||
|
child: TextFormField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
hintText: "Min",
|
||||||
|
),
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
initialValue: widget.recipeStep.waitMin.toString(),
|
||||||
|
onChanged: (String newMin) {
|
||||||
|
setState(() {
|
||||||
|
widget.recipeStep.waitMin = int.tryParse(newMin) ?? 0;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Expanded(
|
||||||
|
flex: 2,
|
||||||
|
child: Center(child: Text("To")),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
flex: 2,
|
||||||
|
child: TextFormField(
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
hintText: "Max",
|
||||||
|
),
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
initialValue: widget.recipeStep.waitMax.toString(),
|
||||||
|
onChanged: (String newMax) {
|
||||||
|
setState(() {
|
||||||
|
widget.recipeStep.waitMax = int.tryParse(newMax) ?? 0;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
flex: 4,
|
||||||
|
child: DropdownButton<String>(
|
||||||
|
value: widget.recipeStep.waitUnit,
|
||||||
|
items: waitUnits,
|
||||||
|
onChanged: (String? newUnit){
|
||||||
|
if (newUnit == null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setState(() {
|
||||||
|
widget.recipeStep.waitUnit = newUnit;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
)
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const Divider(),
|
||||||
|
const Center(child: Text("Sub Steps")),
|
||||||
|
Container(
|
||||||
|
color: Colors.blue,
|
||||||
|
child: TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
widget.recipeStep.subSteps.add(
|
||||||
|
RecipeSubStep("Sub step ${widget.recipeStep.subSteps.length+1}", "")
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: const Text("Add Sub Step", style: TextStyle(color: Colors.white)),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
const Divider()
|
||||||
|
] + widget.recipeStep.subSteps.map((subStep) => buildSubStepRow(subStep)).toList()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget buildSubStepRow(RecipeSubStep subStep){
|
||||||
|
return Row(
|
||||||
|
children: <Widget>[
|
||||||
|
Expanded(
|
||||||
|
flex: 10,
|
||||||
|
child: Text(subStep.name)
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
flex: 4,
|
||||||
|
child: Container(
|
||||||
|
color: Colors.blue,
|
||||||
|
child: TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
FocusScope.of(context).unfocus();
|
||||||
|
Navigator.pushNamed(context, "/recipes/add/edit_sub_step", arguments: subStep).then(
|
||||||
|
(_) {
|
||||||
|
setState((){});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: const Text("Edit", style: TextStyle(color: Colors.white)),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
widget.recipeStep.subSteps.remove(subStep);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: const Text("X", style: TextStyle(color: Colors.red)),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
97
lib/pages/edit_recipe_sub_step_page.dart
Normal file
97
lib/pages/edit_recipe_sub_step_page.dart
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:pizzaplanner/entities/PizzaRecipe/recipe_substep.dart';
|
||||||
|
import 'package:pizzaplanner/pages/add_recipe_page.dart';
|
||||||
|
import 'package:pizzaplanner/pages/scaffold.dart';
|
||||||
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
|
class EditRecipeSubStepPage extends StatefulWidget {
|
||||||
|
final RecipeSubStep subStep;
|
||||||
|
|
||||||
|
const EditRecipeSubStepPage(this.subStep);
|
||||||
|
|
||||||
|
@override
|
||||||
|
EditRecipeSubStepPageState createState() => EditRecipeSubStepPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class EditRecipeSubStepPageState extends State<EditRecipeSubStepPage> {
|
||||||
|
|
||||||
|
bool nameValidation = false;
|
||||||
|
bool descriptionValidation = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context){
|
||||||
|
return PizzaPlannerScaffold(
|
||||||
|
title: Text("Edit: ${widget.subStep.name}"),
|
||||||
|
resizeToAvoidBottomInset: true,
|
||||||
|
body: Column(
|
||||||
|
children: <Widget>[
|
||||||
|
TextFormField(
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: "Recipe Name",
|
||||||
|
errorText: nameValidation ? """Name can't be empty""" : null
|
||||||
|
),
|
||||||
|
initialValue: widget.subStep.name,
|
||||||
|
onChanged: (String newName) {
|
||||||
|
setState(() {
|
||||||
|
widget.subStep.name = newName;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const Divider(),
|
||||||
|
TextFormField(
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: "Recipe Description",
|
||||||
|
errorText: descriptionValidation ? """Description can't be empty""" : null
|
||||||
|
),
|
||||||
|
initialValue: widget.subStep.description,
|
||||||
|
maxLines: 12,
|
||||||
|
onChanged: (String newDescription) {
|
||||||
|
setState(() {
|
||||||
|
widget.subStep.description = newDescription;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const Divider(),
|
||||||
|
Row(
|
||||||
|
children: <Widget>[
|
||||||
|
Expanded(
|
||||||
|
flex: 2,
|
||||||
|
child: Container(
|
||||||
|
color: Colors.blue,
|
||||||
|
width: double.infinity,
|
||||||
|
child: TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return PreviewMarkdownDescription(widget.subStep.description);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: const Text("Preview", style: TextStyle(color: Colors.white)),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
const Expanded(
|
||||||
|
child: SizedBox()
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
flex: 2,
|
||||||
|
child: Container(
|
||||||
|
color: Colors.blue,
|
||||||
|
width: double.infinity,
|
||||||
|
child: TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
launch("https://guides.github.com/features/mastering-markdown/");
|
||||||
|
},
|
||||||
|
child: const Text("Markdown?", style: TextStyle(color: Colors.white)),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
3
todo.md
3
todo.md
|
@ -1,8 +1,7 @@
|
||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
## Feature
|
## Feature
|
||||||
- add a page to create your own recipe
|
- longpress recipe to edit it on recipes page?
|
||||||
- longpress recipe to edit it?
|
|
||||||
- add search to recipes page
|
- add search to recipes page
|
||||||
- add directory structure to recipes?
|
- add directory structure to recipes?
|
||||||
- share to/export of yaml of recipes
|
- share to/export of yaml of recipes
|
||||||
|
|
Loading…
Add table
Reference in a new issue