merge
This commit is contained in:
commit
dc7e94b37b
@ -98,7 +98,7 @@ data class UpdateUserRequest(val userName: String, val email: String)
|
||||
fun updateUser(ctx: Context, username: String, email: String) {
|
||||
val request = UpdateUserRequest(username, email)
|
||||
|
||||
return requestJson<UpdateUserRequest, Unit>(ctx, "PUT", "/api/User/update", request)
|
||||
requestJson<UpdateUserRequest, Boolean>(ctx, "PUT", "/api/User/update", request)
|
||||
}
|
||||
|
||||
@Serializable
|
||||
|
@ -0,0 +1,20 @@
|
||||
package tech.mercantec.easyeat.helpers
|
||||
|
||||
import android.content.Context
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class ShoppingListItem(val id: Int, val name: String, val amount: Double?, val unit: String?, val checked: Boolean)
|
||||
|
||||
fun getShoppingList(ctx: Context): Array<ShoppingListItem> {
|
||||
return requestJson<Unit, Array<ShoppingListItem>>(ctx, "GET", "/api/ShoppingList/get", null)
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class AddShoppingItemRequest(val name: String, val amount: Double?, val unit: String?, val checked: Boolean)
|
||||
|
||||
fun addShoppingItem(ctx: Context, name: String, amount: Double?, unit: String?) {
|
||||
val request = AddShoppingItemRequest(name, amount, unit, false)
|
||||
|
||||
requestJson<AddShoppingItemRequest, Boolean>(ctx, "POST", "/api/ShoppingList/add", request)
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package tech.mercantec.easyeat.ui.profile
|
||||
|
||||
import android.app.ProgressDialog
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.widget.Button
|
||||
import android.widget.EditText
|
||||
@ -43,6 +44,11 @@ class EditProfileActivity : AppCompatActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
val intent = Intent()
|
||||
intent.putExtra("username", username)
|
||||
intent.putExtra("email", email)
|
||||
setResult(RESULT_OK, intent)
|
||||
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,15 @@
|
||||
package tech.mercantec.easyeat.ui.profile
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.core.view.children
|
||||
import androidx.fragment.app.Fragment
|
||||
import tech.mercantec.easyeat.ui.auth.WelcomeActivity
|
||||
import tech.mercantec.easyeat.databinding.FragmentProfileBinding
|
||||
@ -16,8 +20,25 @@ import tech.mercantec.easyeat.helpers.logout
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
class ProfileFragment : Fragment() {
|
||||
private lateinit var launcher: ActivityResultLauncher<Intent>
|
||||
private lateinit var binding: FragmentProfileBinding
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
launcher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
||||
if (it.data == null || it.resultCode != Activity.RESULT_OK) return@registerForActivityResult
|
||||
|
||||
binding.username.text = it.data!!.getStringExtra("username")
|
||||
binding.email.text = it.data!!.getStringExtra("email")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
val binding = FragmentProfileBinding.inflate(inflater, container, false)
|
||||
binding = FragmentProfileBinding.inflate(inflater, container, false)
|
||||
|
||||
binding.layout.children.forEach { it.visibility = View.GONE }
|
||||
binding.loading.visibility = View.VISIBLE
|
||||
|
||||
thread {
|
||||
val userInfo: UserInfoResponse
|
||||
@ -29,6 +50,11 @@ class ProfileFragment : Fragment() {
|
||||
}
|
||||
|
||||
return@thread
|
||||
} finally {
|
||||
activity?.runOnUiThread {
|
||||
binding.layout.children.forEach { it.visibility = View.VISIBLE }
|
||||
binding.loading.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
activity?.runOnUiThread {
|
||||
@ -37,9 +63,10 @@ class ProfileFragment : Fragment() {
|
||||
|
||||
binding.editProfile.setOnClickListener {
|
||||
val intent = Intent(activity, EditProfileActivity::class.java)
|
||||
intent.putExtra("username", userInfo.userName)
|
||||
intent.putExtra("email", userInfo.email)
|
||||
startActivity(intent)
|
||||
intent.putExtra("username", binding.username.text)
|
||||
intent.putExtra("email", binding.email.text)
|
||||
|
||||
launcher.launch(intent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,21 @@
|
||||
package tech.mercantec.easyeat.ui.shopping_list
|
||||
|
||||
import android.app.AlertDialog
|
||||
import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.EditText
|
||||
import android.widget.Spinner
|
||||
import android.widget.Toast
|
||||
import androidx.fragment.app.Fragment
|
||||
import tech.mercantec.easyeat.R
|
||||
import tech.mercantec.easyeat.databinding.FragmentShoppingListBinding
|
||||
import tech.mercantec.easyeat.helpers.ApiRequestException
|
||||
import tech.mercantec.easyeat.helpers.addShoppingItem
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
class ShoppingListFragment : Fragment() {
|
||||
|
||||
@ -32,12 +38,33 @@ class ShoppingListFragment : Fragment() {
|
||||
|
||||
val dialog = AlertDialog.Builder(activity)
|
||||
.setView(view)
|
||||
.setPositiveButton(R.string.add_label, { dialog, id ->
|
||||
.setPositiveButton(R.string.add_label) { dialog, id ->
|
||||
val dialog = dialog as AlertDialog
|
||||
|
||||
})
|
||||
.setNegativeButton(R.string.cancel_label, { dialog, id ->
|
||||
val amount = view.findViewById<EditText>(R.id.amount).text.toString().toDouble()
|
||||
val unit = view.findViewById<Spinner>(R.id.unit_selector).selectedItem.toString().ifEmpty { null }
|
||||
val name = view.findViewById<EditText>(R.id.name).text.toString()
|
||||
|
||||
dialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = false
|
||||
dialog.getButton(AlertDialog.BUTTON_NEGATIVE).isEnabled = false
|
||||
|
||||
thread {
|
||||
try {
|
||||
addShoppingItem(requireContext(), name, amount, unit)
|
||||
} catch (e: ApiRequestException) {
|
||||
activity?.runOnUiThread {
|
||||
Toast.makeText(context, e.message, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
} finally {
|
||||
activity?.runOnUiThread {
|
||||
dialog.dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.setNegativeButton(R.string.cancel_label) { dialog, _ ->
|
||||
dialog.cancel()
|
||||
})
|
||||
}
|
||||
.create()
|
||||
|
||||
dialog.show()
|
||||
|
@ -30,12 +30,14 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/amount_label"
|
||||
android:layout_alignParentStart="true"
|
||||
android:inputType="numberDecimal"
|
||||
android:importantForAutofill="no"
|
||||
android:hint="@string/ingredient_amount_hint"
|
||||
/>
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/unit_selector"
|
||||
android:layout_width="72dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_toEndOf="@id/amount"
|
||||
android:layout_below="@+id/amount_label"
|
||||
@ -57,6 +59,8 @@
|
||||
android:layout_below="@id/name_label"
|
||||
android:layout_toEndOf="@id/unit_selector"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:inputType="text"
|
||||
android:importantForAutofill="no"
|
||||
android:hint="@string/ingredient_name_hint"
|
||||
/>
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
@ -30,7 +31,6 @@
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:textAlignment="center"
|
||||
android:text="@string/loading"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
@ -40,7 +40,6 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="18sp"
|
||||
android:textAlignment="center"
|
||||
android:text="@string/loading"
|
||||
/>
|
||||
|
||||
<LinearLayout
|
||||
|
@ -39,6 +39,7 @@
|
||||
<string name="change_password_label">Change password</string>
|
||||
<string name="logout_label">Log out</string>
|
||||
<string-array name="units">
|
||||
<item></item>
|
||||
<item>g</item>
|
||||
<item>kg</item>
|
||||
<item>ml</item>
|
||||
|
@ -16,8 +16,8 @@ namespace API.BusinessLogic
|
||||
/// <summary>
|
||||
/// Gets all the recipes from _dbaccess and checks if there are any
|
||||
/// </summary>
|
||||
/// <param name="userId"></param>
|
||||
/// <returns></returns>
|
||||
/// <param name="userId">the usér connected to the recipes</param>
|
||||
/// <returns>a list of recipes in a ok objectresult</returns>
|
||||
public async Task<IActionResult> GetRecipes(int userId)
|
||||
{
|
||||
var recipes = await _dbAccess.ReadRecipes(userId);
|
||||
@ -26,7 +26,7 @@ namespace API.BusinessLogic
|
||||
return new OkObjectResult(recipes);
|
||||
}
|
||||
|
||||
//
|
||||
// Gets a specifik with recipe with the ingredient and directions
|
||||
public async Task<IActionResult> GetRecipe(int recipeId)
|
||||
{
|
||||
var recipe = await _dbAccess.ReadRecipe(recipeId);
|
||||
@ -36,6 +36,13 @@ namespace API.BusinessLogic
|
||||
return new OkObjectResult(recipe);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a recipe and checks if the recipe name is in use
|
||||
/// Converts the recipeDTO to a normal recipe
|
||||
/// </summary>
|
||||
/// <param name="recipe">The recipeDTO that does not include all the id tags</param>
|
||||
/// <param name="userId">The user that is going to get that recipe</param>
|
||||
/// <returns>returns what recipedbaccess gives back</returns>
|
||||
public async Task<IActionResult> CreateRecipe(RecipeDTO recipe, int userId)
|
||||
{
|
||||
var recipes = await _dbAccess.ReadRecipes(userId);
|
||||
@ -71,6 +78,13 @@ namespace API.BusinessLogic
|
||||
return await _dbAccess.CreateRecipe(dish, userId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the recipe that is saved in the db
|
||||
/// </summary>
|
||||
/// <param name="recipe">The updated recipe</param>
|
||||
/// <param name="recipeId">The recipeId on the recipe to be updated</param>
|
||||
/// <param name="userId">The userÍd of the owner of the to be updated recipe</param>
|
||||
/// <returns>returns what recipedbaccess gives back</returns>
|
||||
public async Task<IActionResult> EditRecipe(RecipeDTO recipe, int recipeId, int userId)
|
||||
{
|
||||
var recipes = await _dbAccess.ReadRecipes(userId);
|
||||
@ -105,13 +119,14 @@ namespace API.BusinessLogic
|
||||
return await _dbAccess.UpdateRecipe(dish);
|
||||
}
|
||||
|
||||
// Deletes the recipe
|
||||
public async Task<IActionResult> DeleteRecipe(int recipeId)
|
||||
{
|
||||
var recipe = await _dbAccess.ReadRecipe(recipeId);
|
||||
|
||||
if (recipe != null) { return await _dbAccess.DeleteUser(recipe); }
|
||||
if (recipe != null) { return await _dbAccess.DeleteRecipe(recipe); }
|
||||
|
||||
return new ConflictObjectResult(new { message = "Invalid user" });
|
||||
return new ConflictObjectResult(new { message = "Invalid recipe" });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ namespace API.BusinessLogic
|
||||
_recipeDBAccess = recipeDBAccess;
|
||||
}
|
||||
|
||||
// Reads the current shooping list of the user
|
||||
public async Task<IActionResult> ReadShoppingList(int userId)
|
||||
{
|
||||
var user = await _dbAccess.ReadShoppingList(userId);
|
||||
@ -22,6 +23,7 @@ namespace API.BusinessLogic
|
||||
return new OkObjectResult(user.ShoppingList);
|
||||
}
|
||||
|
||||
// Adds an item to the shoppinglist and checks if the unit should be changed and if the name is the same as an item already on the shoppinglist
|
||||
public async Task<IActionResult> AddItemToShoppingList(ShoppingListItemDTO listItemDTO, int userId)
|
||||
{
|
||||
var user = await _dbAccess.ReadShoppingList(userId);
|
||||
@ -42,12 +44,12 @@ namespace API.BusinessLogic
|
||||
item.Amount = (item.Amount / 1000) + listItemDTO.Amount;
|
||||
item.Unit = "kg";
|
||||
}
|
||||
else if (item.Unit == "ml" && item.Unit == "l")
|
||||
else if (item.Unit == "ml" && listItemDTO.Unit == "l")
|
||||
{
|
||||
item.Amount = (item.Amount / 1000) + listItemDTO.Amount;
|
||||
item.Unit = "l";
|
||||
}
|
||||
else if (item.Unit == "dl" && item.Unit == "l")
|
||||
else if (item.Unit == "dl" && listItemDTO.Unit == "l")
|
||||
{
|
||||
item.Amount = (item.Amount / 10) + listItemDTO.Amount;
|
||||
item.Unit = "l";
|
||||
@ -85,6 +87,7 @@ namespace API.BusinessLogic
|
||||
return await _dbAccess.UpdateShoppingList(user);
|
||||
}
|
||||
|
||||
// Gets the shoppinglist and tries to find the item and when it does it checks/unchecks that item
|
||||
public async Task<IActionResult> CheckItemInShoppingList(int userId, int itemId)
|
||||
{
|
||||
var user = await _dbAccess.ReadShoppingList(userId);
|
||||
@ -96,6 +99,7 @@ namespace API.BusinessLogic
|
||||
return await _dbAccess.UpdateShoppingList(user);
|
||||
}
|
||||
|
||||
// Updates an item on the shopping list to what the user specified
|
||||
public async Task<IActionResult> UpdateItemInShoppingList(int userId, int itemId, ShoppingListItemDTO listItemDTO)
|
||||
{
|
||||
var user = await _dbAccess.ReadShoppingList(userId);
|
||||
@ -125,6 +129,7 @@ namespace API.BusinessLogic
|
||||
return await _dbAccess.UpdateShoppingList(user);
|
||||
}
|
||||
|
||||
// Deletes an item from the shopping list if it is on the users shoppinglist
|
||||
public async Task<IActionResult> DeleteItemInShoppingList(int userId, int itemId)
|
||||
{
|
||||
var user = await _dbAccess.ReadShoppingList(userId);
|
||||
@ -136,6 +141,7 @@ namespace API.BusinessLogic
|
||||
return await _dbAccess.UpdateShoppingList(user);
|
||||
}
|
||||
|
||||
// Adds an entire recipes ingredients to the shoppinglist
|
||||
public async Task<IActionResult> AddRecipeToShoppingList(int userId, int recipeId)
|
||||
{
|
||||
var user = await _dbAccess.ReadShoppingList(userId);
|
||||
|
@ -23,6 +23,7 @@ namespace API.BusinessLogic
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
// Gets an user from their id
|
||||
public async Task<IActionResult> GetUser(int userId)
|
||||
{
|
||||
User user = await _dbAccess.ReadUser(userId);
|
||||
@ -31,6 +32,7 @@ namespace API.BusinessLogic
|
||||
return new OkObjectResult(new { user.Id, user.UserName, user.Email });
|
||||
}
|
||||
|
||||
// Checks if the userdata is ok before the user is created and creats the othere list's that the user have
|
||||
public async Task<IActionResult> RegisterUser(CreateUserDTO userDTO)
|
||||
{
|
||||
if (!EmailCheck(userDTO.Email))
|
||||
@ -71,6 +73,7 @@ namespace API.BusinessLogic
|
||||
return await _dbAccess.CreateUser(user);
|
||||
}
|
||||
|
||||
// Checks if the username/email matches the password and generates a jwttoken if it is correct
|
||||
public async Task<IActionResult> Login(LoginDTO loginDTO)
|
||||
{
|
||||
var user = await _dbAccess.ReadUserForLogin(loginDTO.EmailUsr);
|
||||
@ -91,6 +94,7 @@ namespace API.BusinessLogic
|
||||
return new ConflictObjectResult(new { message = "Invalid password" });
|
||||
}
|
||||
|
||||
// Checks if the username or email is already in use and changes them if they are diffrent from before
|
||||
public async Task<IActionResult> EditProfile(UpdateUserDTO userDTO, int userId)
|
||||
{
|
||||
var profile = await _dbAccess.ReadUser(userId);
|
||||
@ -142,6 +146,7 @@ namespace API.BusinessLogic
|
||||
return await _dbAccess.UpdateUser(profile);
|
||||
}
|
||||
|
||||
// Checks if the old password is correct and then it checks if the password is secure enough
|
||||
public async Task<IActionResult> ChangePassword(ChangePasswordDTO passwordDTO, int userId)
|
||||
{
|
||||
var user = await _dbAccess.ReadUser(userId);
|
||||
@ -167,6 +172,7 @@ namespace API.BusinessLogic
|
||||
return await _dbAccess.UpdatePassword(user);
|
||||
}
|
||||
|
||||
// Checks if the user exist and it deletes that user
|
||||
public async Task<IActionResult> DeleteUser(int userId)
|
||||
{
|
||||
var user = await _dbAccess.ReadUserForDelete(userId);
|
||||
@ -176,6 +182,7 @@ namespace API.BusinessLogic
|
||||
return new ConflictObjectResult(new { message = "Invalid user" });
|
||||
}
|
||||
|
||||
// Checks if the refreshtoken is correct and if it is it generates a new jwttoken and refreshtoken
|
||||
public async Task<IActionResult> RefreshToken(string refreshToken)
|
||||
{
|
||||
User user = await _dbAccess.ReadUserByRefreshToken(refreshToken);
|
||||
@ -185,6 +192,7 @@ namespace API.BusinessLogic
|
||||
return new OkObjectResult(new { token = jwtToken, refreshToken = user.RefreshToken });
|
||||
}
|
||||
|
||||
// Checks if the password is up to our security standard
|
||||
private bool PasswordSecurity(string password)
|
||||
{
|
||||
var hasMinimum8Chars = new Regex(@".{8,}");
|
||||
@ -192,11 +200,19 @@ namespace API.BusinessLogic
|
||||
return hasMinimum8Chars.IsMatch(password);
|
||||
}
|
||||
|
||||
// Checks if the email has all the things an email should have
|
||||
private bool EmailCheck(string email)
|
||||
{
|
||||
return new Regex(@".+@.+\..+").IsMatch(email);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a hash from a salt and input using the algorithm that is provided
|
||||
/// </summary>
|
||||
/// <param name="input">This is the input that is supposed to be hashed</param>
|
||||
/// <param name="algorithm">This is the alogorithm that is used to encrypt the input</param>
|
||||
/// <param name="salt">This is something extra added to make the hashed input more unpredictable</param>
|
||||
/// <returns>The hashed input</returns>
|
||||
private static string ComputeHash(string input, HashAlgorithm algorithm, string salt)
|
||||
{
|
||||
Byte[] inputBytes = Encoding.UTF8.GetBytes(input);
|
||||
@ -212,6 +228,7 @@ namespace API.BusinessLogic
|
||||
return BitConverter.ToString(hashedBytes);
|
||||
}
|
||||
|
||||
// Generates a jwttoken that contains the users id and username and a unique identifier that is valid for 1 hour
|
||||
private string GenerateJwtToken(User user)
|
||||
{
|
||||
var claims = new[]
|
||||
@ -235,6 +252,7 @@ namespace API.BusinessLogic
|
||||
return new JwtSecurityTokenHandler().WriteToken(token);
|
||||
}
|
||||
|
||||
// Generate a new refreshtoken that expire after 30 days
|
||||
private async Task<User> UpdateRefreshToken(User user)
|
||||
{
|
||||
user.RefreshToken = Guid.NewGuid().ToString();
|
||||
|
@ -20,6 +20,10 @@ namespace API.Controllers
|
||||
_openAiRecipes = openAiRecipes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the userId from the jwt token amd returns a list of recipes without their ingredients and directions
|
||||
/// </summary>
|
||||
/// <returns>returns a okobjectresult with a list of recipes if it fails it returns a confliftobjectresult with a message of why it failed</returns>
|
||||
[Authorize]
|
||||
[HttpGet("getall")]
|
||||
public async Task<IActionResult> ReadRecipes()
|
||||
@ -30,6 +34,11 @@ namespace API.Controllers
|
||||
return await _recipeLogic.GetRecipes(userId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a specifik recipe including the ingredients and directions
|
||||
/// </summary>
|
||||
/// <param name="recipeId">The recipe that is you want</param>
|
||||
/// <returns>returns a okobjectresult with a recipe if it fails it returns a confliftobjectresult with a message of why it failed</returns>
|
||||
[Authorize]
|
||||
[HttpGet("get/{recipeId}")]
|
||||
public async Task<IActionResult> ReadRecipe(int recipeId)
|
||||
@ -37,6 +46,11 @@ namespace API.Controllers
|
||||
return await _recipeLogic.GetRecipe(recipeId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a recipe and adds it to the users recipes
|
||||
/// </summary>
|
||||
/// <param name="recipe">The recipe to be added</param>
|
||||
/// <returns>returns a okobjectresult with a boolean that is true if it fails it returns a confliftobjectresult with a message of why it failed</returns>
|
||||
[Authorize]
|
||||
[HttpPost("create")]
|
||||
public async Task<IActionResult> CreateRecipe([FromBody] RecipeDTO recipe)
|
||||
@ -47,6 +61,12 @@ namespace API.Controllers
|
||||
return await _recipeLogic.CreateRecipe(recipe, userId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Edits a recipe
|
||||
/// </summary>
|
||||
/// <param name="recipe">the edited recipe</param>
|
||||
/// <param name="recipeId">the recipe to be edited</param>
|
||||
/// <returns>returns a okobjectresult with a boolean that is true if it fails it returns a confliftobjectresult with a message of why it failed</returns>
|
||||
[Authorize]
|
||||
[HttpPut("edit/{recipeId}")]
|
||||
public async Task<IActionResult> EditRecipe([FromBody] RecipeDTO recipe, int recipeId)
|
||||
@ -57,6 +77,11 @@ namespace API.Controllers
|
||||
return await _recipeLogic.EditRecipe(recipe, recipeId, userId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletess a recipe
|
||||
/// </summary>
|
||||
/// <param name="recipeId">the id of the recipe to be deleted</param>
|
||||
/// <returns>returns a okobjectresult with a boolean that is true if it fails it returns a confliftobjectresult with a message of why it failed</returns>
|
||||
[Authorize]
|
||||
[HttpDelete("delete/{recipeId}")]
|
||||
public async Task<IActionResult> DeleteRecipe(int recipeId)
|
||||
@ -64,6 +89,11 @@ namespace API.Controllers
|
||||
return await _recipeLogic.DeleteRecipe(recipeId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a recipe using chatgpt
|
||||
/// </summary>
|
||||
/// <param name="recipeDTO">Contains all the infomation that is needed to generate a recipe</param>
|
||||
/// <returns>returns a list of generated recipes</returns>
|
||||
[Authorize]
|
||||
[HttpPost("chatbot")]
|
||||
public async Task<IActionResult> GenerateRecipe([FromBody] GenerateRecipeDTO recipeDTO)
|
||||
|
@ -1,6 +1,7 @@
|
||||
|
||||
using API.BusinessLogic;
|
||||
using API.Models.ShoppingListModels;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Security.Claims;
|
||||
|
||||
@ -17,6 +18,11 @@ namespace API.Controllers
|
||||
_shoppingListLogic = shoppingListLogic;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the entire shoppinglist connected to the user
|
||||
/// </summary>
|
||||
/// <returns>returns a list of shoppinglist items if it fails it returns a confliftobjectresult with a message of why it failed</returns>
|
||||
[Authorize]
|
||||
[HttpGet("get")]
|
||||
public async Task<IActionResult> ReadShoppingList()
|
||||
{
|
||||
@ -26,6 +32,12 @@ namespace API.Controllers
|
||||
return await _shoppingListLogic.ReadShoppingList(userId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds an item to the shopping list
|
||||
/// </summary>
|
||||
/// <param name="listItemDTO"></param>
|
||||
/// <returns></returns>
|
||||
[Authorize]
|
||||
[HttpPost("add")]
|
||||
public async Task<IActionResult> AddItem([FromBody] ShoppingListItemDTO listItemDTO)
|
||||
{
|
||||
@ -35,6 +47,12 @@ namespace API.Controllers
|
||||
return await _shoppingListLogic.AddItemToShoppingList(listItemDTO, userId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks/Unchecks an item on the shoppinglist
|
||||
/// </summary>
|
||||
/// <param name="itemId">The item to be checked/unchecked</param>
|
||||
/// <returns>returns a okobjectresult with a boolean that is true if it fails it returns a confliftobjectresult with a message of why it failed</returns>
|
||||
[Authorize]
|
||||
[HttpPut("check")]
|
||||
public async Task<IActionResult> CheckItem(int itemId)
|
||||
{
|
||||
@ -44,6 +62,13 @@ namespace API.Controllers
|
||||
return await _shoppingListLogic.CheckItemInShoppingList(userId, itemId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Edits an item on the shoppinglist
|
||||
/// </summary>
|
||||
/// <param name="listItemDTO">The edited item</param>
|
||||
/// <param name="itemId">The item to be edited</param>
|
||||
/// <returns>returns a okobjectresult with a boolean that is true if it fails it returns a confliftobjectresult with a message of why it failed</returns>
|
||||
[Authorize]
|
||||
[HttpPut("update")]
|
||||
public async Task<IActionResult> UpdateItem([FromBody] ShoppingListItemDTO listItemDTO, int itemId)
|
||||
{
|
||||
@ -53,6 +78,12 @@ namespace API.Controllers
|
||||
return await _shoppingListLogic.UpdateItemInShoppingList(userId, itemId, listItemDTO);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes an item on the shoppinglist
|
||||
/// </summary>
|
||||
/// <param name="itemId">The item to be deleted</param>
|
||||
/// <returns>returns a okobjectresult with a boolean that is true if it fails it returns a confliftobjectresult with a message of why it failed</returns>
|
||||
[Authorize]
|
||||
[HttpDelete("delete")]
|
||||
public async Task<IActionResult> DeleteItem(int itemId)
|
||||
{
|
||||
@ -62,6 +93,12 @@ namespace API.Controllers
|
||||
return await _shoppingListLogic.DeleteItemInShoppingList(userId, itemId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add an entire recipes ingredients to the shoppinglist
|
||||
/// </summary>
|
||||
/// <param name="recipeId">The recipes ingredients to be added</param>
|
||||
/// <returns>returns a okobjectresult with a boolean that is true if it fails it returns a confliftobjectresult with a message of why it failed</returns>
|
||||
[Authorize]
|
||||
[HttpPost("recipeadd")]
|
||||
public async Task<IActionResult> AddARecipesItems(int recipeId)
|
||||
{
|
||||
|
@ -17,6 +17,10 @@ namespace API.Controllers
|
||||
_userLogic = userLogic;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the users email and username
|
||||
/// </summary>
|
||||
/// <returns>returns the users email, username and Id</returns>
|
||||
[Authorize]
|
||||
[HttpGet("get")]
|
||||
public async Task<IActionResult> ReadUser()
|
||||
@ -27,18 +31,33 @@ namespace API.Controllers
|
||||
return await _userLogic.GetUser(userId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logins a user
|
||||
/// </summary>
|
||||
/// <param name="loginDTO">The users login credentials</param>
|
||||
/// <returns>Returns a jwttoken their username, id and a refreshtoken</returns>
|
||||
[HttpPost("login")]
|
||||
public async Task<IActionResult> Login([FromBody] LoginDTO loginDTO)
|
||||
{
|
||||
return await _userLogic.Login(loginDTO);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new user
|
||||
/// </summary>
|
||||
/// <param name="userDTO">contains the username email and password</param>
|
||||
/// <returns>returns a okobjectresult with a boolean that is true if it fails it returns a confliftobjectresult with a message of why it failed</returns>
|
||||
[HttpPost("create")]
|
||||
public async Task<IActionResult> CreateUser([FromBody] CreateUserDTO userDTO)
|
||||
{
|
||||
return await _userLogic.RegisterUser(userDTO);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the password of the user
|
||||
/// </summary>
|
||||
/// <param name="passwordDTO">Contains the old password and the new one</param>
|
||||
/// <returns>returns a okobjectresult with a boolean that is true if it fails it returns a confliftobjectresult with a message of why it failed</returns>
|
||||
[Authorize]
|
||||
[HttpPut("change-password")]
|
||||
public async Task<IActionResult> ChangePassword([FromBody] ChangePasswordDTO passwordDTO)
|
||||
@ -49,6 +68,11 @@ namespace API.Controllers
|
||||
return await _userLogic.ChangePassword(passwordDTO, userId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Edits the email and username of the user
|
||||
/// </summary>
|
||||
/// <param name="userDTO">The updated username and email</param>
|
||||
/// <returns>returns a okobjectresult with a boolean that is true if it fails it returns a confliftobjectresult with a message of why it failed</returns>
|
||||
[Authorize]
|
||||
[HttpPut("update")]
|
||||
public async Task<IActionResult> UpdateUser([FromBody] UpdateUserDTO userDTO)
|
||||
@ -59,6 +83,10 @@ namespace API.Controllers
|
||||
return await _userLogic.EditProfile(userDTO, userId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the user
|
||||
/// </summary>
|
||||
/// <returns>returns a okobjectresult with a boolean that is true if it fails it returns a confliftobjectresult with a message of why it failed</returns>
|
||||
[Authorize]
|
||||
[HttpDelete("delete")]
|
||||
public async Task<IActionResult> DeleteUser()
|
||||
@ -69,6 +97,11 @@ namespace API.Controllers
|
||||
return await _userLogic.DeleteUser(userId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For when the jwt token is outdated
|
||||
/// </summary>
|
||||
/// <param name="refreshToken">contains a string with the refreshtoken</param>
|
||||
/// <returns>returns a new refreshtoken and new jwt token</returns>
|
||||
[HttpPost("refreshtoken")]
|
||||
public async Task<IActionResult> RefreashToken([FromBody] RefreshTokenDTO refreshToken)
|
||||
{
|
||||
|
@ -14,6 +14,7 @@ namespace API.DBAccess
|
||||
_context = context;
|
||||
}
|
||||
|
||||
// Reads the users recipes
|
||||
public async Task<List<Recipe>> ReadRecipes(int userId)
|
||||
{
|
||||
var recipes = await _context.Users.Include(p => p.Recipes).FirstOrDefaultAsync(u => u.Id == userId);
|
||||
@ -21,11 +22,13 @@ namespace API.DBAccess
|
||||
return recipes.Recipes;
|
||||
}
|
||||
|
||||
// Returns a specifik recipe
|
||||
public async Task<Recipe> ReadRecipe(int recipeId)
|
||||
{
|
||||
return await _context.Recipes.Include(r => r.Ingredients).FirstOrDefaultAsync(r => r.Id == recipeId);
|
||||
return await _context.Recipes.Include(r => r.Ingredients).Include(r => r.Directions).FirstOrDefaultAsync(r => r.Id == recipeId);
|
||||
}
|
||||
|
||||
// Adds a new recipe to the database
|
||||
public async Task<IActionResult> CreateRecipe(Recipe recipe, int userId)
|
||||
{
|
||||
var recipes = await _context.Users.Include(p => p.Recipes).FirstOrDefaultAsync(u => u.Id == userId);
|
||||
@ -39,6 +42,7 @@ namespace API.DBAccess
|
||||
return new ConflictObjectResult(new { message = "Could not save to database" });
|
||||
}
|
||||
|
||||
// Updates the recipe in the database
|
||||
public async Task<IActionResult> UpdateRecipe(Recipe recipe)
|
||||
{
|
||||
_context.Entry(recipe).State = EntityState.Modified;
|
||||
@ -50,7 +54,8 @@ namespace API.DBAccess
|
||||
return new ConflictObjectResult(new { message = "Could not save to database" });
|
||||
}
|
||||
|
||||
public async Task<IActionResult> DeleteUser(Recipe recipe)
|
||||
// Deletes the recipe from the database
|
||||
public async Task<IActionResult> DeleteRecipe(Recipe recipe)
|
||||
{
|
||||
_context.Recipes.Remove(recipe);
|
||||
bool saved = await _context.SaveChangesAsync() >= 0;
|
||||
|
@ -14,6 +14,8 @@ namespace API.DBAccess
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
// Read the shoppinglist connected to the user
|
||||
public async Task<User> ReadShoppingList(int userId)
|
||||
{
|
||||
var user = await _context.Users.Include(u => u.ShoppingList).FirstOrDefaultAsync(u => u.Id == userId);
|
||||
@ -21,13 +23,14 @@ namespace API.DBAccess
|
||||
return user;
|
||||
}
|
||||
|
||||
// Updates the shoppinglist
|
||||
public async Task<IActionResult> UpdateShoppingList(User user)
|
||||
{
|
||||
_context.Entry(user).State = EntityState.Modified;
|
||||
|
||||
bool saved = await _context.SaveChangesAsync() >= 1;
|
||||
|
||||
if (saved) { return new OkObjectResult(user); }
|
||||
if (saved) { return new OkObjectResult(true); }
|
||||
|
||||
return new ConflictObjectResult(new { message = "Could not save to database" });
|
||||
}
|
||||
|
@ -13,16 +13,19 @@ namespace API.DBAccess
|
||||
_context = context;
|
||||
}
|
||||
|
||||
// Reads the user from the database
|
||||
public async Task<User> ReadUser(int userId)
|
||||
{
|
||||
return await _context.Users.FirstOrDefaultAsync(u => u.Id == userId);
|
||||
}
|
||||
|
||||
// Reads all the users from the database
|
||||
public async Task<List<User>> ReadAllUsers()
|
||||
{
|
||||
return await _context.Users.ToListAsync();
|
||||
}
|
||||
|
||||
// Searches for a user with the username
|
||||
public async Task<bool> UserNameInUse(string username)
|
||||
{
|
||||
var user = await _context.Users.FirstOrDefaultAsync(u => u.UserName == username);
|
||||
@ -30,6 +33,7 @@ namespace API.DBAccess
|
||||
return true;
|
||||
}
|
||||
|
||||
// Searches for a user with the email
|
||||
public async Task<bool> EmailInUse(string email)
|
||||
{
|
||||
var user = await _context.Users.FirstOrDefaultAsync(u => u.UserName == email);
|
||||
@ -37,16 +41,19 @@ namespace API.DBAccess
|
||||
return true;
|
||||
}
|
||||
|
||||
// Searches for a user with refreshtoken and returns that user
|
||||
public async Task<User> ReadUserByRefreshToken(string refreshToken)
|
||||
{
|
||||
return await _context.Users.FirstOrDefaultAsync(u => u.RefreshToken == refreshToken);
|
||||
}
|
||||
|
||||
// Gets all the data for a user
|
||||
public async Task<User> ReadUserForDelete(int userId)
|
||||
{
|
||||
return await _context.Users.FirstOrDefaultAsync(u => u.Id == userId);
|
||||
return await _context.Users.Include(u => u.Recipes).ThenInclude(r => r.Ingredients).Include(u => u.Recipes).ThenInclude(r => r.Directions).Include(u => u.ShoppingList).FirstOrDefaultAsync(u => u.Id == userId);
|
||||
}
|
||||
|
||||
// Gets a user according to either the email or username
|
||||
public async Task<User> ReadUserForLogin(string emailOrUsername)
|
||||
{
|
||||
if (emailOrUsername.Contains("@"))
|
||||
@ -59,6 +66,7 @@ namespace API.DBAccess
|
||||
}
|
||||
}
|
||||
|
||||
// Adds a new user to the database
|
||||
public async Task<IActionResult> CreateUser(User user)
|
||||
{
|
||||
_context.Users.Add(user);
|
||||
@ -71,17 +79,19 @@ namespace API.DBAccess
|
||||
|
||||
}
|
||||
|
||||
// Updates the user in the database
|
||||
public async Task<IActionResult> UpdateUser(User user)
|
||||
{
|
||||
_context.Entry(user).State = EntityState.Modified;
|
||||
|
||||
bool saved = await _context.SaveChangesAsync() == 1;
|
||||
|
||||
if (saved) { return new OkObjectResult(user); }
|
||||
if (saved) { return new OkObjectResult(true); }
|
||||
|
||||
return new ConflictObjectResult(new { message = "Could not save to database" });
|
||||
}
|
||||
|
||||
// Updates the password in the database
|
||||
public async Task<IActionResult> UpdatePassword(User user)
|
||||
{
|
||||
_context.Entry(user).State = EntityState.Modified;
|
||||
@ -93,6 +103,7 @@ namespace API.DBAccess
|
||||
return new ConflictObjectResult(new { message = "Could not save to database" });
|
||||
}
|
||||
|
||||
// Deletes the user from the database
|
||||
public async Task<IActionResult> DeleteUser(User user)
|
||||
{
|
||||
_context.Users.Remove(user);
|
||||
|
Loading…
Reference in New Issue
Block a user