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 {
|
||||
alias(libs.plugins.android.application)
|
||||
alias(libs.plugins.kotlin.android)
|
||||
id("kotlin-parcelize")
|
||||
id("org.jetbrains.kotlin.plugin.serialization")
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,10 @@
|
||||
android:name=".ui.dishes.DishDetailsActivity"
|
||||
android:exported="false" />
|
||||
|
||||
<activity
|
||||
android:name=".ui.dishes.EditDishActivity"
|
||||
android:exported="false" />
|
||||
|
||||
<activity
|
||||
android:name=".ui.profile.ChangePasswordActivity"
|
||||
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)
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class ShoppingListAddRecipeRequest(val multiplier: String)
|
||||
fun AddRecipeToShoppingList(ctx: Context, id: Int, multiplier: String): Boolean {
|
||||
|
||||
fun AddRecipeToShoppingList(ctx: Context, id: Int, multiplier: String) {
|
||||
val request = ShoppingListAddRecipeRequest(multiplier)
|
||||
|
||||
return requestJson<ShoppingListAddRecipeRequest, Unit>(ctx, "POST", "/api/ShoppingList/recipeadd/$id", request)
|
||||
return requestJson<String, Boolean>(ctx, "POST", "/api/ShoppingList/recipeadd/$id", multiplier)
|
||||
}
|
||||
|
@ -16,6 +16,10 @@ fun createRecipe(ctx: Context, recipe: 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
|
||||
data class GetAllRecipesResponse(val id: Int, val name: String, val description: String)
|
||||
|
||||
@ -24,9 +28,9 @@ fun getAllRecipes(ctx: Context): List<GetAllRecipesResponse> {
|
||||
}
|
||||
|
||||
@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 {
|
||||
return requestJson<Unit, RecipeDetailsResponse>(ctx, "GET", "/api/Recipe/get/$id", null)
|
||||
fun getRecipeDetails(ctx: Context, id: Int): Recipe {
|
||||
return requestJson<Unit, Recipe>(ctx, "GET", "/api/Recipe/get/$id", null)
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@ package tech.mercantec.easyeat.models
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
|
||||
@Serializable
|
||||
data class Recipe(
|
||||
val id: Int? = null,
|
||||
|
@ -25,7 +25,7 @@ class CreateDishActivity : AppCompatActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_create_dish_form)
|
||||
setContentView(R.layout.activity_dish_form)
|
||||
|
||||
ingredientContainer = findViewById(R.id.ingredientContainer)
|
||||
val addButton: Button = findViewById(R.id.addIngredientButton)
|
||||
@ -84,7 +84,7 @@ class CreateDishActivity : AppCompatActivity() {
|
||||
|
||||
private fun addIngredientRow() {
|
||||
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)
|
||||
spinnerMeasurements.adapter = ArrayAdapter(
|
||||
this,
|
||||
|
@ -2,17 +2,17 @@ package tech.mercantec.easyeat.ui.dishes
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.ProgressDialog
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.text.Html
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import kotlinx.serialization.encodeToString
|
||||
import kotlinx.serialization.json.Json
|
||||
import android.widget.Button
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.Toast
|
||||
import tech.mercantec.easyeat.R
|
||||
import tech.mercantec.easyeat.helpers.ApiRequestException
|
||||
import tech.mercantec.easyeat.helpers.RecipeDetailsResponse
|
||||
import tech.mercantec.easyeat.helpers.getRecipeDetails
|
||||
import kotlin.concurrent.thread
|
||||
import android.widget.EditText
|
||||
@ -22,6 +22,7 @@ import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.widget.doAfterTextChanged
|
||||
import tech.mercantec.easyeat.helpers.AddRecipeToShoppingList
|
||||
import tech.mercantec.easyeat.models.Ingredient
|
||||
import tech.mercantec.easyeat.models.Recipe
|
||||
|
||||
class DishDetailsActivity : AppCompatActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
@ -39,7 +40,7 @@ class DishDetailsActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
thread {
|
||||
val recipe: RecipeDetailsResponse
|
||||
val recipe: Recipe
|
||||
try {
|
||||
recipe = getRecipeDetails(this, dishId)
|
||||
} catch (e: ApiRequestException) {
|
||||
@ -143,13 +144,21 @@ class DishDetailsActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
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)
|
||||
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:padding="30sp"
|
||||
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
|
||||
android:id="@+id/dishDetailName"
|
||||
android:layout_width="match_parent"
|
||||
|
@ -56,6 +56,7 @@
|
||||
<string name="instructions_label">Instructions</string>
|
||||
<string name="increment_multiplier_desc">Increment portion count</string>
|
||||
<string name="decrement_multiplier_desc">Decrement portion size</string>
|
||||
<string name="edit_recipe">Edit Recipe</string>
|
||||
<string-array name="units">
|
||||
<item></item>
|
||||
<item>g</item>
|
||||
|
@ -111,7 +111,7 @@ namespace API.BusinessLogic
|
||||
|
||||
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." });
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user