updates to editrecipe
This commit is contained in:
parent
5c924026ed
commit
4a935514cf
@ -3,6 +3,7 @@ import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties
|
|||||||
plugins {
|
plugins {
|
||||||
alias(libs.plugins.android.application)
|
alias(libs.plugins.android.application)
|
||||||
alias(libs.plugins.kotlin.android)
|
alias(libs.plugins.kotlin.android)
|
||||||
|
id("kotlin-parcelize")
|
||||||
id("org.jetbrains.kotlin.plugin.serialization")
|
id("org.jetbrains.kotlin.plugin.serialization")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,6 +52,10 @@
|
|||||||
android:name=".ui.dishes.DishDetailsActivity"
|
android:name=".ui.dishes.DishDetailsActivity"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".ui.dishes.EditDishActivity"
|
||||||
|
android:exported="false" />
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.profile.ChangePasswordActivity"
|
android:name=".ui.profile.ChangePasswordActivity"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
|
@ -112,11 +112,7 @@ fun changePassword(ctx: Context, oldPassword: String, newPassword: String) {
|
|||||||
return requestJson<ChangePasswordRequest, Unit>(ctx, "PUT", "/api/User/change-password", request)
|
return requestJson<ChangePasswordRequest, Unit>(ctx, "PUT", "/api/User/change-password", request)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
fun AddRecipeToShoppingList(ctx: Context, id: Int, multiplier: String): Boolean {
|
||||||
data class ShoppingListAddRecipeRequest(val multiplier: String)
|
|
||||||
|
|
||||||
fun AddRecipeToShoppingList(ctx: Context, id: Int, multiplier: String) {
|
return requestJson<String, Boolean>(ctx, "POST", "/api/ShoppingList/recipeadd/$id", multiplier)
|
||||||
val request = ShoppingListAddRecipeRequest(multiplier)
|
|
||||||
|
|
||||||
return requestJson<ShoppingListAddRecipeRequest, Unit>(ctx, "POST", "/api/ShoppingList/recipeadd/$id", request)
|
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,10 @@ fun createRecipe(ctx: Context, recipe: Recipe) {
|
|||||||
requestJson<Recipe, Boolean>(ctx, "POST", "/api/recipe/create", recipe)
|
requestJson<Recipe, Boolean>(ctx, "POST", "/api/recipe/create", recipe)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun updateRecipe(ctx: Context, id: Int, recipe: Recipe) {
|
||||||
|
requestJson<Recipe, Boolean>(ctx, "PUT", "/api/recipe/edit/$id", recipe)
|
||||||
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class GetAllRecipesResponse(val id: Int, val name: String, val description: String)
|
data class GetAllRecipesResponse(val id: Int, val name: String, val description: String)
|
||||||
|
|
||||||
@ -24,9 +28,9 @@ fun getAllRecipes(ctx: Context): List<GetAllRecipesResponse> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class RecipeDetailsResponse(val id: Int, val name: String, val description: String, val directions: List<String>, val ingredients: List<Ingredient>)
|
data class RecipeDetailsResponse(val recipe: Recipe)
|
||||||
|
|
||||||
fun getRecipeDetails(ctx: Context, id: Int): RecipeDetailsResponse {
|
fun getRecipeDetails(ctx: Context, id: Int): Recipe {
|
||||||
return requestJson<Unit, RecipeDetailsResponse>(ctx, "GET", "/api/Recipe/get/$id", null)
|
return requestJson<Unit, Recipe>(ctx, "GET", "/api/Recipe/get/$id", null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package tech.mercantec.easyeat.models
|
|||||||
|
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class Recipe(
|
data class Recipe(
|
||||||
val id: Int? = null,
|
val id: Int? = null,
|
||||||
|
@ -25,7 +25,7 @@ class CreateDishActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_create_dish_form)
|
setContentView(R.layout.activity_dish_form)
|
||||||
|
|
||||||
ingredientContainer = findViewById(R.id.ingredientContainer)
|
ingredientContainer = findViewById(R.id.ingredientContainer)
|
||||||
val addButton: Button = findViewById(R.id.addIngredientButton)
|
val addButton: Button = findViewById(R.id.addIngredientButton)
|
||||||
@ -84,7 +84,7 @@ class CreateDishActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
private fun addIngredientRow() {
|
private fun addIngredientRow() {
|
||||||
val inflater = LayoutInflater.from(this)
|
val inflater = LayoutInflater.from(this)
|
||||||
val ingredientRow = inflater.inflate(R.layout.activity_create_dish_ingredient_row, null)
|
val ingredientRow = inflater.inflate(R.layout.activity_dish_ingredient_row, null)
|
||||||
val spinnerMeasurements = ingredientRow.findViewById<Spinner>(R.id.measurementsDropDown)
|
val spinnerMeasurements = ingredientRow.findViewById<Spinner>(R.id.measurementsDropDown)
|
||||||
spinnerMeasurements.adapter = ArrayAdapter(
|
spinnerMeasurements.adapter = ArrayAdapter(
|
||||||
this,
|
this,
|
||||||
|
@ -2,17 +2,17 @@ package tech.mercantec.easyeat.ui.dishes
|
|||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.app.ProgressDialog
|
import android.app.ProgressDialog
|
||||||
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.Html
|
import android.text.Html
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.View
|
import kotlinx.serialization.encodeToString
|
||||||
import android.view.ViewGroup
|
import kotlinx.serialization.json.Json
|
||||||
import android.widget.Button
|
import android.widget.Button
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import tech.mercantec.easyeat.R
|
import tech.mercantec.easyeat.R
|
||||||
import tech.mercantec.easyeat.helpers.ApiRequestException
|
import tech.mercantec.easyeat.helpers.ApiRequestException
|
||||||
import tech.mercantec.easyeat.helpers.RecipeDetailsResponse
|
|
||||||
import tech.mercantec.easyeat.helpers.getRecipeDetails
|
import tech.mercantec.easyeat.helpers.getRecipeDetails
|
||||||
import kotlin.concurrent.thread
|
import kotlin.concurrent.thread
|
||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
@ -22,6 +22,7 @@ import androidx.appcompat.app.AppCompatActivity
|
|||||||
import androidx.core.widget.doAfterTextChanged
|
import androidx.core.widget.doAfterTextChanged
|
||||||
import tech.mercantec.easyeat.helpers.AddRecipeToShoppingList
|
import tech.mercantec.easyeat.helpers.AddRecipeToShoppingList
|
||||||
import tech.mercantec.easyeat.models.Ingredient
|
import tech.mercantec.easyeat.models.Ingredient
|
||||||
|
import tech.mercantec.easyeat.models.Recipe
|
||||||
|
|
||||||
class DishDetailsActivity : AppCompatActivity() {
|
class DishDetailsActivity : AppCompatActivity() {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
@ -39,7 +40,7 @@ class DishDetailsActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
thread {
|
thread {
|
||||||
val recipe: RecipeDetailsResponse
|
val recipe: Recipe
|
||||||
try {
|
try {
|
||||||
recipe = getRecipeDetails(this, dishId)
|
recipe = getRecipeDetails(this, dishId)
|
||||||
} catch (e: ApiRequestException) {
|
} catch (e: ApiRequestException) {
|
||||||
@ -143,13 +144,21 @@ class DishDetailsActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
Toast.makeText(this, "Password changed successfully", Toast.LENGTH_LONG).show()
|
Toast.makeText(this, "Recipe ingredients added to shopping", Toast.LENGTH_LONG).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
setResult(Activity.RESULT_OK)
|
setResult(Activity.RESULT_OK)
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
val editRecipeBtn: Button = findViewById(R.id.editRecipeBtn)
|
||||||
|
editRecipeBtn.setOnClickListener {
|
||||||
|
val jsonRecipe = Json.encodeToString(recipe) // convert Recipe to JSON string
|
||||||
|
val intent = Intent(this, EditDishActivity::class.java)
|
||||||
|
intent.putExtra("recipe_json", jsonRecipe) // put as string
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,154 @@
|
|||||||
|
package tech.mercantec.easyeat.ui.dishes
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.app.ProgressDialog
|
||||||
|
import kotlinx.serialization.encodeToString
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.widget.ArrayAdapter
|
||||||
|
import android.widget.Button
|
||||||
|
import android.widget.EditText
|
||||||
|
import android.widget.ImageButton
|
||||||
|
import android.widget.LinearLayout
|
||||||
|
import android.widget.Spinner
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import tech.mercantec.easyeat.R
|
||||||
|
import tech.mercantec.easyeat.helpers.ApiRequestException
|
||||||
|
import tech.mercantec.easyeat.helpers.createRecipe
|
||||||
|
import tech.mercantec.easyeat.helpers.updateRecipe
|
||||||
|
import tech.mercantec.easyeat.models.Ingredient
|
||||||
|
import tech.mercantec.easyeat.models.Recipe
|
||||||
|
import kotlin.concurrent.thread
|
||||||
|
|
||||||
|
class EditDishActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
private lateinit var ingredientContainer: LinearLayout
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_dish_form)
|
||||||
|
|
||||||
|
val recipe: Recipe? = intent.getStringExtra("recipe_json")?.let {
|
||||||
|
try {
|
||||||
|
Json.decodeFromString<Recipe>(it)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val dishName = findViewById<EditText>(R.id.dishName)
|
||||||
|
val dishDescription = findViewById<EditText>(R.id.dishDescription)
|
||||||
|
val instructions = findViewById<EditText>(R.id.instructions)
|
||||||
|
val saveButton = findViewById<Button>(R.id.saveDishButton)
|
||||||
|
ingredientContainer = findViewById(R.id.ingredientContainer)
|
||||||
|
|
||||||
|
// Populate UI
|
||||||
|
dishName.setText(recipe?.name)
|
||||||
|
dishDescription.setText(recipe?.description)
|
||||||
|
instructions.setText(recipe?.directions?.joinToString("\n"))
|
||||||
|
|
||||||
|
for (ingredient in recipe?.ingredients!!) {
|
||||||
|
addIngredientRow(ingredient)
|
||||||
|
}
|
||||||
|
|
||||||
|
findViewById<Button>(R.id.addIngredientButton).setOnClickListener {
|
||||||
|
addIngredientRow()
|
||||||
|
}
|
||||||
|
|
||||||
|
saveButton.setOnClickListener {
|
||||||
|
saveButton.setOnClickListener {
|
||||||
|
val ingredientList = collectIngredients()
|
||||||
|
val instructions = findViewById<EditText>(R.id.instructions).text.toString().trim()
|
||||||
|
val directions: List<String> = instructions
|
||||||
|
.split("\n")
|
||||||
|
.map { line -> line.trim() }
|
||||||
|
.filter { it.isNotEmpty() }
|
||||||
|
|
||||||
|
val updatedRecipe = Recipe(
|
||||||
|
name = findViewById<EditText>(R.id.dishName).text.toString().trim(),
|
||||||
|
description = findViewById<EditText>(R.id.dishDescription).text.toString().trim(),
|
||||||
|
directions = directions,
|
||||||
|
ingredients = ingredientList
|
||||||
|
)
|
||||||
|
|
||||||
|
val progressDialog = ProgressDialog(this)
|
||||||
|
progressDialog.setMessage("Loading...")
|
||||||
|
progressDialog.show()
|
||||||
|
thread {
|
||||||
|
try {
|
||||||
|
updateRecipe(this, recipe.id!!, updatedRecipe)
|
||||||
|
} catch (e: ApiRequestException) {
|
||||||
|
runOnUiThread {
|
||||||
|
Toast.makeText(this, e.message, Toast.LENGTH_LONG).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
return@thread
|
||||||
|
} finally {
|
||||||
|
runOnUiThread {
|
||||||
|
progressDialog.hide()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
runOnUiThread {
|
||||||
|
Toast.makeText(this, "Password changed successfully", Toast.LENGTH_LONG).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
setResult(Activity.RESULT_OK)
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addIngredientRow(ingredient: Ingredient? = null) {
|
||||||
|
val inflater = LayoutInflater.from(this)
|
||||||
|
val ingredientRow = inflater.inflate(R.layout.activity_dish_ingredient_row, null)
|
||||||
|
val nameField = ingredientRow.findViewById<EditText>(R.id.ingredientNameEditText)
|
||||||
|
val amountField = ingredientRow.findViewById<EditText>(R.id.ingredientAmountEditText)
|
||||||
|
val unitSpinner = ingredientRow.findViewById<Spinner>(R.id.measurementsDropDown)
|
||||||
|
|
||||||
|
unitSpinner.adapter = ArrayAdapter(
|
||||||
|
this,
|
||||||
|
android.R.layout.simple_spinner_item,
|
||||||
|
listOf("g", "kg", "ml", "l", "tsp", "tbsp", "cup", "pcs", "pinch", "dash")
|
||||||
|
)
|
||||||
|
|
||||||
|
if (ingredient != null) {
|
||||||
|
nameField.setText(ingredient.name)
|
||||||
|
amountField.setText(ingredient.amount.toString())
|
||||||
|
unitSpinner.setSelection((unitSpinner.adapter as ArrayAdapter<String>).getPosition(ingredient.unit))
|
||||||
|
}
|
||||||
|
|
||||||
|
ingredientRow.findViewById<ImageButton>(R.id.removeButton).setOnClickListener {
|
||||||
|
ingredientContainer.removeView(ingredientRow)
|
||||||
|
}
|
||||||
|
|
||||||
|
ingredientContainer.addView(ingredientRow)
|
||||||
|
}
|
||||||
|
private fun collectIngredients(): List<Ingredient> {
|
||||||
|
val ingredients = mutableListOf<Ingredient>()
|
||||||
|
|
||||||
|
for (i in 0 until ingredientContainer.childCount) {
|
||||||
|
val ingredientView = ingredientContainer.getChildAt(i)
|
||||||
|
|
||||||
|
// Find views inside this ingredient row
|
||||||
|
|
||||||
|
val ingredientEditText = ingredientView.findViewById<EditText>(R.id.ingredientNameEditText)
|
||||||
|
val amountEditText = ingredientView.findViewById<EditText>(R.id.ingredientAmountEditText)
|
||||||
|
val spinner = ingredientView.findViewById<Spinner>(R.id.measurementsDropDown)
|
||||||
|
|
||||||
|
val element = ingredientEditText.text.toString().trim()
|
||||||
|
val amount = amountEditText.text.toString().trim()
|
||||||
|
val unit = spinner.selectedItem.toString()
|
||||||
|
|
||||||
|
// Optional: Only add non-empty rows
|
||||||
|
if (element.isNotEmpty() && amount.isNotEmpty()) {
|
||||||
|
ingredients.add(Ingredient(name = element, amount = amount.toDouble(), unit = unit))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ingredients
|
||||||
|
}
|
||||||
|
}
|
@ -9,7 +9,15 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:padding="30sp"
|
android:padding="30sp"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
<Button
|
||||||
|
android:id="@+id/editRecipeBtn"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="end"
|
||||||
|
android:backgroundTint="@color/cyan"
|
||||||
|
android:text="@string/edit_recipe"
|
||||||
|
android:tint="@android:color/white"
|
||||||
|
/>
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/dishDetailName"
|
android:id="@+id/dishDetailName"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -56,6 +56,7 @@
|
|||||||
<string name="instructions_label">Instructions</string>
|
<string name="instructions_label">Instructions</string>
|
||||||
<string name="increment_multiplier_desc">Increment portion count</string>
|
<string name="increment_multiplier_desc">Increment portion count</string>
|
||||||
<string name="decrement_multiplier_desc">Decrement portion size</string>
|
<string name="decrement_multiplier_desc">Decrement portion size</string>
|
||||||
|
<string name="edit_recipe">Edit Recipe</string>
|
||||||
<string-array name="units">
|
<string-array name="units">
|
||||||
<item></item>
|
<item></item>
|
||||||
<item>g</item>
|
<item>g</item>
|
||||||
|
@ -111,7 +111,7 @@ namespace API.BusinessLogic
|
|||||||
|
|
||||||
foreach (var item in recipes)
|
foreach (var item in recipes)
|
||||||
{
|
{
|
||||||
if (item.Name == recipe.Name)
|
if (item.Name == recipe.Name && item.Name != dish.Name)
|
||||||
{
|
{
|
||||||
return new ConflictObjectResult(new { message = "Recipe name is already in use." });
|
return new ConflictObjectResult(new { message = "Recipe name is already in use." });
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user