From 56017f745d32ee6dfa37be53fdde71ed95c1aa51 Mon Sep 17 00:00:00 2001 From: LilleBRG Date: Tue, 13 May 2025 10:55:24 +0200 Subject: [PATCH] dishlist works and dishgdetails soon done --- app/app/src/main/AndroidManifest.xml | 4 ++ .../tech/mercantec/easyeat/helpers/auth.kt | 23 +++++--- .../mercantec/easyeat/models/CreateRecipe.kt | 24 ++++++++ .../tech/mercantec/easyeat/models/recipe.kt | 12 ++-- .../easyeat/ui/dishes/CreateDishActivity.kt | 18 +++--- .../easyeat/ui/dishes/DishAdapter.kt | 16 +++-- .../easyeat/ui/dishes/DishDetailsActivity.kt | 54 +++++++++++++++++ .../easyeat/ui/dishes/DishesFragment.kt | 22 +++---- .../easyeat/ui/dishes/IngredientAdapter.kt | 30 ++++++++++ .../easyeat/ui/dishes/InstructionsAdapter.kt | 26 +++++++++ .../res/layout/activity_create_dish_form.xml | 12 +++- .../activity_create_dish_ingredient_row.xml | 3 +- .../main/res/layout/activity_dish_details.xml | 58 +++++++++++++++++++ ...vity_dish_details_ingredient_list_item.xml | 34 +++++++++++ ...ty_dish_details_instructions_list_item.xml | 19 ++++++ 15 files changed, 315 insertions(+), 40 deletions(-) create mode 100644 app/app/src/main/java/tech/mercantec/easyeat/models/CreateRecipe.kt create mode 100644 app/app/src/main/java/tech/mercantec/easyeat/ui/dishes/DishDetailsActivity.kt create mode 100644 app/app/src/main/java/tech/mercantec/easyeat/ui/dishes/IngredientAdapter.kt create mode 100644 app/app/src/main/java/tech/mercantec/easyeat/ui/dishes/InstructionsAdapter.kt create mode 100644 app/app/src/main/res/layout/activity_dish_details.xml create mode 100644 app/app/src/main/res/layout/activity_dish_details_ingredient_list_item.xml create mode 100644 app/app/src/main/res/layout/activity_dish_details_instructions_list_item.xml diff --git a/app/app/src/main/AndroidManifest.xml b/app/app/src/main/AndroidManifest.xml index 69e6466..10e464a 100644 --- a/app/app/src/main/AndroidManifest.xml +++ b/app/app/src/main/AndroidManifest.xml @@ -48,6 +48,10 @@ android:name=".ui.dishes.CreateDishAIActivity" android:exported="false" /> + + diff --git a/app/app/src/main/java/tech/mercantec/easyeat/helpers/auth.kt b/app/app/src/main/java/tech/mercantec/easyeat/helpers/auth.kt index a804e43..6ce46f1 100644 --- a/app/app/src/main/java/tech/mercantec/easyeat/helpers/auth.kt +++ b/app/app/src/main/java/tech/mercantec/easyeat/helpers/auth.kt @@ -1,12 +1,14 @@ package tech.mercantec.easyeat.helpers -import android.content.ClipDescription import android.content.Context import android.util.Log import kotlinx.serialization.Serializable +import tech.mercantec.easyeat.models.CreateDirection +import tech.mercantec.easyeat.models.CreateIngredient +import tech.mercantec.easyeat.models.CreateRecipe import tech.mercantec.easyeat.models.Direction import tech.mercantec.easyeat.models.Ingredient -import tech.mercantec.easyeat.models.Recipe + @Serializable data class LoginRequest(val emailUsr: String, val password: String) @@ -114,17 +116,24 @@ fun changePassword(ctx: Context, oldPassword: String, newPassword: String) { } @Serializable -data class CreateRecipeRequest(val name: String, val description: String, val directions: List, val ingredients: List) +data class CreateRecipeRequest(val name: String, val description: String, val directions: List, val ingredients: List) -fun createRecipe(ctx: Context, recipe: Recipe) { +fun createRecipe(ctx: Context, recipe: CreateRecipe) { val request = CreateRecipeRequest(recipe.name, recipe.description, recipe.directions, recipe.ingredients) requestJson(ctx, "POST", "/api/recipe/create", request) } @Serializable -data class RecipeResponse(val id: Int, val name: String, val description: String) +data class GetAllRecipesResponse(val id: Int, val name: String, val description: String) -fun getRecipies(ctx: Context): List { - return requestJson>(ctx, "GET", "/api/Recipe/getall", null) +fun getAllRecipies(ctx: Context): List { + return requestJson>(ctx, "GET", "/api/Recipe/getall", null) +} + +@Serializable +data class RecipeDetailsResponse(val id: Int, val name: String, val description: String, val directions: List, val ingredients: List) + +fun getRecipeDetails(ctx: Context, id: Int): RecipeDetailsResponse { + return requestJson(ctx, "GET", "/api/Recipe/get/$id", null) } diff --git a/app/app/src/main/java/tech/mercantec/easyeat/models/CreateRecipe.kt b/app/app/src/main/java/tech/mercantec/easyeat/models/CreateRecipe.kt new file mode 100644 index 0000000..782f449 --- /dev/null +++ b/app/app/src/main/java/tech/mercantec/easyeat/models/CreateRecipe.kt @@ -0,0 +1,24 @@ +package tech.mercantec.easyeat.models + +import kotlinx.serialization.Serializable + +@Serializable +data class CreateRecipe( + val name: String, + val description: String, + val directions: List, + val ingredients: List +) + +@Serializable +data class CreateDirection( + val instructions: String +) + + +@Serializable +data class CreateIngredient( + val amount: Double?, + val unit: String?, + val name: String +) \ No newline at end of file diff --git a/app/app/src/main/java/tech/mercantec/easyeat/models/recipe.kt b/app/app/src/main/java/tech/mercantec/easyeat/models/recipe.kt index 1215baa..1a1c7a1 100644 --- a/app/app/src/main/java/tech/mercantec/easyeat/models/recipe.kt +++ b/app/app/src/main/java/tech/mercantec/easyeat/models/recipe.kt @@ -2,23 +2,27 @@ package tech.mercantec.easyeat.models import kotlinx.serialization.Serializable + @Serializable data class Recipe( + val id: Int, val name: String, val description: String, - val directions: List, - val ingredients: List + val directions: List, + val ingredients: List ) @Serializable data class Direction( - val instructions: String + val id: Int, + val instruktions: String ) @Serializable data class Ingredient( + val id: Int, val amount: Double?, val unit: String?, val name: String -) +) \ No newline at end of file diff --git a/app/app/src/main/java/tech/mercantec/easyeat/ui/dishes/CreateDishActivity.kt b/app/app/src/main/java/tech/mercantec/easyeat/ui/dishes/CreateDishActivity.kt index e6fdd74..74e6060 100644 --- a/app/app/src/main/java/tech/mercantec/easyeat/ui/dishes/CreateDishActivity.kt +++ b/app/app/src/main/java/tech/mercantec/easyeat/ui/dishes/CreateDishActivity.kt @@ -20,9 +20,9 @@ import tech.mercantec.easyeat.helpers.ApiRequestException import tech.mercantec.easyeat.helpers.changePassword import tech.mercantec.easyeat.helpers.createRecipe import tech.mercantec.easyeat.helpers.request -import tech.mercantec.easyeat.models.Direction -import tech.mercantec.easyeat.models.Ingredient -import tech.mercantec.easyeat.models.Recipe +import tech.mercantec.easyeat.models.CreateDirection +import tech.mercantec.easyeat.models.CreateIngredient +import tech.mercantec.easyeat.models.CreateRecipe import kotlin.concurrent.thread class CreateDishActivity : AppCompatActivity() { @@ -48,13 +48,13 @@ class CreateDishActivity : AppCompatActivity() { saveButton.setOnClickListener { val ingredientList = collectIngredients() val instructions = findViewById(R.id.instructions).text.toString().trim() - val directions: List = instructions + val directions: List = instructions .split("\n") .map { line -> line.trim() } .filter { it.isNotEmpty() } - .map { line -> Direction(instructions = line) } + .map { line -> CreateDirection(instructions = line) } - val recipe = Recipe( + val recipe = CreateRecipe( name = findViewById(R.id.dishName).text.toString().trim(), description = findViewById(R.id.dishDescription).text.toString().trim(), directions = directions, @@ -109,8 +109,8 @@ class CreateDishActivity : AppCompatActivity() { ingredientContainer.addView(ingredientRow) } - private fun collectIngredients(): List { - val ingredients = mutableListOf() + private fun collectIngredients(): List { + val ingredients = mutableListOf() for (i in 0 until ingredientContainer.childCount) { val ingredientView = ingredientContainer.getChildAt(i) @@ -127,7 +127,7 @@ class CreateDishActivity : AppCompatActivity() { // Optional: Only add non-empty rows if (element.isNotEmpty() && amount.isNotEmpty()) { - ingredients.add(Ingredient(name = element, amount = amount.toDouble(), unit = unit)) + ingredients.add(CreateIngredient(name = element, amount = amount.toDouble(), unit = unit)) } } diff --git a/app/app/src/main/java/tech/mercantec/easyeat/ui/dishes/DishAdapter.kt b/app/app/src/main/java/tech/mercantec/easyeat/ui/dishes/DishAdapter.kt index 5b72d04..467aecb 100644 --- a/app/app/src/main/java/tech/mercantec/easyeat/ui/dishes/DishAdapter.kt +++ b/app/app/src/main/java/tech/mercantec/easyeat/ui/dishes/DishAdapter.kt @@ -9,8 +9,11 @@ import android.widget.TextView import tech.mercantec.easyeat.R import tech.mercantec.easyeat.models.DishListItem -class DishAdapter(context: Context, dishes: List) : - ArrayAdapter(context, 0, dishes) { +class DishAdapter( + context: Context, + private val dishes: List, + private val onDishClick: (DishListItem) -> Unit +) : ArrayAdapter(context, 0, dishes) { override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { val dish = getItem(position) @@ -19,9 +22,14 @@ class DishAdapter(context: Context, dishes: List) : val nameTextView = view.findViewById(R.id.dishName) val descriptionTextView = view.findViewById(R.id.descriptionTextView) - nameTextView.text = "Name: ${dish?.name}" - descriptionTextView.text = "Description: ${dish?.description}" + nameTextView.text = dish?.name + descriptionTextView.text = dish?.description + + view.setOnClickListener { + dish?.let { onDishClick(it) } + } return view } } + diff --git a/app/app/src/main/java/tech/mercantec/easyeat/ui/dishes/DishDetailsActivity.kt b/app/app/src/main/java/tech/mercantec/easyeat/ui/dishes/DishDetailsActivity.kt new file mode 100644 index 0000000..3f41774 --- /dev/null +++ b/app/app/src/main/java/tech/mercantec/easyeat/ui/dishes/DishDetailsActivity.kt @@ -0,0 +1,54 @@ +package tech.mercantec.easyeat.ui.dishes + +import android.os.Bundle +import android.util.Log +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.RecipeDetailsResponse +import tech.mercantec.easyeat.helpers.getRecipeDetails +import kotlin.concurrent.thread +import android.widget.ListView +import android.widget.TextView + +class DishDetailsActivity : AppCompatActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_dish_details) + + val dishId = intent.getIntExtra("dish_id", -1) + if (dishId == -1) { + Toast.makeText(this, "No dish ID provided", Toast.LENGTH_SHORT).show() + finish() + return + } + + thread { + val recipe: RecipeDetailsResponse + try { + recipe = getRecipeDetails(this, dishId) + } catch (e: ApiRequestException) { + runOnUiThread { + Toast.makeText(this, e.message, Toast.LENGTH_LONG).show() + } + return@thread + } + Log.i("DISH", recipe.ingredients.toString()) + runOnUiThread { + // Set title and description + findViewById(R.id.dishDetailName).text = recipe.name + findViewById(R.id.dishDetailDescription).text = recipe.description + + // Set up the ingredient list + val ingredientListView = findViewById(R.id.dishDetailIngredients) + val ingredientAdapter = IngredientAdapter(this, recipe.ingredients) + ingredientListView.adapter = ingredientAdapter + + val instructionsListView = findViewById(R.id.dishDetailInstructions) + val instructionsAdapter = InstructionsAdapter(this, recipe.directions) + instructionsListView.adapter = instructionsAdapter + } + } + } +} \ No newline at end of file diff --git a/app/app/src/main/java/tech/mercantec/easyeat/ui/dishes/DishesFragment.kt b/app/app/src/main/java/tech/mercantec/easyeat/ui/dishes/DishesFragment.kt index 2910543..4e1a301 100644 --- a/app/app/src/main/java/tech/mercantec/easyeat/ui/dishes/DishesFragment.kt +++ b/app/app/src/main/java/tech/mercantec/easyeat/ui/dishes/DishesFragment.kt @@ -3,7 +3,6 @@ package tech.mercantec.easyeat.ui.dishes import android.app.Activity import android.content.Intent import android.os.Bundle -import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -12,16 +11,12 @@ import android.widget.Toast import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts import androidx.fragment.app.Fragment -import androidx.lifecycle.lifecycleScope -import kotlinx.coroutines.launch import tech.mercantec.easyeat.R import tech.mercantec.easyeat.databinding.FragmentDishesBinding import tech.mercantec.easyeat.helpers.ApiRequestException -import tech.mercantec.easyeat.helpers.RecipeResponse -import tech.mercantec.easyeat.helpers.getRecipies -import tech.mercantec.easyeat.helpers.login +import tech.mercantec.easyeat.helpers.GetAllRecipesResponse +import tech.mercantec.easyeat.helpers.getAllRecipies import tech.mercantec.easyeat.models.DishListItem -import tech.mercantec.easyeat.ui.MainActivity import kotlin.concurrent.thread class DishesFragment : Fragment() { @@ -69,11 +64,11 @@ class DishesFragment : Fragment() { return root } - fun DishesFragment.loadRecipes() { + fun DishesFragment.loadRecipes() { thread { - val recipes: List + val recipes: List try { - recipes = getRecipies(requireContext()) + recipes = getAllRecipies(requireContext()) } catch (e: ApiRequestException) { activity?.runOnUiThread { Toast.makeText(requireContext(), e.message, Toast.LENGTH_LONG).show() @@ -86,7 +81,12 @@ class DishesFragment : Fragment() { } activity?.runOnUiThread { - val adapter = DishAdapter(requireContext(), dishes) + val adapter = DishAdapter(requireContext(), dishes) { selectedDish -> + // Open details activity + val intent = Intent(requireContext(), DishDetailsActivity::class.java) + intent.putExtra("dish_id", selectedDish.id) + startActivity(intent) + } binding.dishesList.adapter = adapter } } diff --git a/app/app/src/main/java/tech/mercantec/easyeat/ui/dishes/IngredientAdapter.kt b/app/app/src/main/java/tech/mercantec/easyeat/ui/dishes/IngredientAdapter.kt new file mode 100644 index 0000000..6540db7 --- /dev/null +++ b/app/app/src/main/java/tech/mercantec/easyeat/ui/dishes/IngredientAdapter.kt @@ -0,0 +1,30 @@ +package tech.mercantec.easyeat.ui.dishes + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ArrayAdapter +import android.widget.TextView +import tech.mercantec.easyeat.R +import tech.mercantec.easyeat.models.Ingredient + +class IngredientAdapter(context: Context, ingredients: List) + : ArrayAdapter(context, 0, ingredients) { + + override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { + val ingredient = getItem(position) + val view = convertView ?: LayoutInflater.from(context) + .inflate(R.layout.activity_dish_details_ingredient_list_item, parent, false) + + val nameView = view.findViewById(R.id.ingredientName) + val amountView = view.findViewById(R.id.ingredientAmount) + val unitView = view.findViewById(R.id.ingredientUnit) + + nameView.text = ingredient?.name ?: "" + amountView.text = ingredient?.amount?.toString() ?: "-" + unitView.text = ingredient?.unit ?: "-" + + return view + } +} diff --git a/app/app/src/main/java/tech/mercantec/easyeat/ui/dishes/InstructionsAdapter.kt b/app/app/src/main/java/tech/mercantec/easyeat/ui/dishes/InstructionsAdapter.kt new file mode 100644 index 0000000..e0a2fee --- /dev/null +++ b/app/app/src/main/java/tech/mercantec/easyeat/ui/dishes/InstructionsAdapter.kt @@ -0,0 +1,26 @@ +package tech.mercantec.easyeat.ui.dishes + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ArrayAdapter +import android.widget.TextView +import tech.mercantec.easyeat.R +import tech.mercantec.easyeat.models.Direction + +class InstructionsAdapter (context: Context, instructions: List) + : ArrayAdapter(context, 0, instructions) { + + override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { + val ingredient = getItem(position) + val view = convertView ?: LayoutInflater.from(context) + .inflate(R.layout.activity_dish_details_instructions_list_item, parent, false) + + val nameView = view.findViewById(R.id.instructionText) + + nameView.text = ingredient?.instruktions ?: "" + + return view + } +} \ No newline at end of file diff --git a/app/app/src/main/res/layout/activity_create_dish_form.xml b/app/app/src/main/res/layout/activity_create_dish_form.xml index cf8dfb1..4ef597b 100644 --- a/app/app/src/main/res/layout/activity_create_dish_form.xml +++ b/app/app/src/main/res/layout/activity_create_dish_form.xml @@ -15,7 +15,9 @@ android:text="@string/general" android:textAlignment="center" android:textSize="24sp" - android:layout_marginTop="20dp"/> + android:layout_marginTop="20dp" + android:textStyle="bold" + /> + android:layout_marginTop="20dp" + android:textStyle="bold" + /> + android:layout_marginTop="20dp" + android:textStyle="bold" + /> + android:layout_height="48dp" /> diff --git a/app/app/src/main/res/layout/activity_dish_details.xml b/app/app/src/main/res/layout/activity_dish_details.xml new file mode 100644 index 0000000..584e952 --- /dev/null +++ b/app/app/src/main/res/layout/activity_dish_details.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/app/src/main/res/layout/activity_dish_details_ingredient_list_item.xml b/app/app/src/main/res/layout/activity_dish_details_ingredient_list_item.xml new file mode 100644 index 0000000..321f6e7 --- /dev/null +++ b/app/app/src/main/res/layout/activity_dish_details_ingredient_list_item.xml @@ -0,0 +1,34 @@ + + + + + + + + + diff --git a/app/app/src/main/res/layout/activity_dish_details_instructions_list_item.xml b/app/app/src/main/res/layout/activity_dish_details_instructions_list_item.xml new file mode 100644 index 0000000..f0370e1 --- /dev/null +++ b/app/app/src/main/res/layout/activity_dish_details_instructions_list_item.xml @@ -0,0 +1,19 @@ + + + + + + + + +