@page "/ViewRecipe/{Id}"
@using Microsoft.AspNetCore.Authorization;
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
@using MyRecipes2.Shared;
@using MyRecipes2.Client.Services;
@inject HttpClient Http;
@inject AuthenticationStateProvider AuthenticationStateProvider;
@inject UtilityService UtilityService;
@inject NavigationManager NavManager;
@if (recipe == null)
{
<p><em>Loading...</em></p>
}
else
{
<div class="col-md-12 col-lg-8">
<h1> @recipe.Name </h1>
<div class="form-row mb-2 ml-1">
@foreach (var mealType in recipe.MealTypes)
{
<button class="btn btn-secondary disabled ml-1 btn-sm"># @mealType.Name</button>
}
</div>
<!-- Photo -->
<div style="display: flex; justify-content: center; align-items: center; height: 30rem; background-image: url(@recipe.ImageUrl); background-size: cover;" class="border">
</div>
<div class="row mt-3 mb-3 ml-3">
<div class="col-6">
<div class="row">
<div style="border-radius: 50%; width: 5rem; height: 5rem; background-image: url(@recipeAuthor.ProfileImageUrl); background-size: cover;">
</div>
<div style="height: 5rem; display: flex; align-items: center;">
<div class="pl-2">
<div @onclick="ViewAuthorProfile" style="cursor: pointer;" class="text-muted btn btn-link p-0 m-0"> @recipe.Author </div>
<div>
<AuthorizeView>
<Authorized>
@if (subscribed == false)
{
<button @onclick="Subscribe" class="btn btn-primary btn-sm mb-2">Subscribe</button>
}
else
{
<button @onclick="() => OpenUnsubPrompt()" class="btn btn-secondary btn-sm mb-2">Unsubscribe</button>
}
</Authorized>
</AuthorizeView>
</div>
</div>
</div>
</div>
</div>
<div class="col-6">
<div style="float: right;">
<div>
<AuthorizeView>
<Authorized>
@if (UserHasLikedRecipe)
{
<button type="button" class="btn btn-secondary" style="margin-right: 0.5rem" @onclick="RemoveLike">
<i class="oi oi-heart"></i>
Liked
</button>
}
else
{
<button type="button" class="btn btn-primary" style="margin-right: 0.5rem" @onclick="AddLike">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-heart" viewBox="0 0 16 16">
<path d="m8 2.748-.717-.737C5.6.281 2.514.878 1.4 3.053c-.523 1.023-.641 2.5.314 4.385.92 1.815 2.834 3.989 6.286 6.357 3.452-2.368 5.365-4.542 6.286-6.357.955-1.886.838-3.362.314-4.385C13.486.878 10.4.28 8.717 2.01L8 2.748zM8 15C-7.333 4.868 3.279-3.04 7.824 1.143c.06.055.119.112.176.171a3.12 3.12 0 0 1 .176-.17C12.72-3.042 23.333 4.867 8 15z" />
</svg>
Like
</button>
}
</Authorized>
</AuthorizeView>
<span>
@recipe.Likes people have liked this recipe
</span>
</div>
</div>
</div>
</div>
<div>
<table class="table">
<thead>
<tr>
<th> Ingredient </th>
<th> Amount </th>
<th> Unit </th>
<th> Calories </th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var ingredient in recipe.Ingredients)
{
<tr>
<td>@ingredient.Name</td>
<td>@ingredient.Quantity </td>
<td>@ingredient.Unit</td>
<td>@ingredient.Calories</td>
<td><button @onclick="() => OpenShoppingModal(ingredient.Name)" class="btn btn-secondary btn-sm mb-2">Shop</button></td>
</tr>
}
</tbody>
</table>
</div>
@*<iframe src="https://www.woolworths.com.au/shop/search/products?searchTerm=chicken" height=500 width=500></iframe>*@
<div>
<b>Total Calories</b>: @recipe.Calories
</div>
<br />
<div>
<table class="table">
<thead>
<tr>
<th> Method </th>
</tr>
</thead>
<tbody>
@foreach (var method in recipe.Method)
{
<tr>
<td>@method</td>
</tr>
}
</tbody>
</table>
</div>
@if (relaitedRecipes != null && relaitedRecipes.Count() > 0)
{
<h4>Related</h4>
<div class="row">
@foreach (var recipe in relaitedRecipes)
{
<RecipeDisplayCard recipe="recipe"></RecipeDisplayCard>
}
</div>
}
<div class=" mt-4">
<div>
<form>
<h4>
Comment(s)
</h4>
<AuthorizeView>
<Authorized>
<div class="form-group">
<textarea @bind="comment" class="form-control" rows="2"></textarea>
</div>
<button class="btn btn-primary mb-2" @onclick="ClickAddComment">Comment</button>
</Authorized>
</AuthorizeView>
</form>
</div>
<div class="row d-flex mt-3 mb-3">
@foreach (var comment in recipe.Comments)
{
<div class="col-md-12">
<div class="card p-3 mt-2" style="border-radius: 3px; margin-bottom: 10px; box-shadow: 5px 5px 5px 1.5px #e8e8e8;">
<div class="d-flex justify-content-between">
<div class="d-flex flex-row">
<span><small class="font-weight-bold text-primary">@comment.User</small> <small class="font-weight-bold ml-2">@comment.Text</small></span>
</div>
<small class="text-muted font-weight-light">@comment.Time</small>
</div>
</div>
</div>
}
</div>
</div>
@if (ShoppingModalOpen)
{
<Modal Title="Ingredient Search Results" Text="Thanks for shopping with our trusted partner - Woolworths!"
OnClose="@OnShoppingModalClose" PromptType="Modal.ModalType.Shopping" ShopURL=@IngredientUrl></Modal>
}
@if (UnsubPromptOpen)
{
<Modal Title="You are about to unsubscribe from this user" Text="Unsubscribe?"
OnClose="@OnUnsubPromptClose" PromptType="Modal.ModalType.UnsubscribeCancel"></Modal>
}
</div>
}
@code {
private RecipeDto recipe;
private bool UserHasLikedRecipe { get; set; }
private string subscribeToId;
private string subscribeFromId;
private bool subscribed;
private UserDto recipeAuthor;
string comment { get; set; }
[Parameter]
public string Id { get; set; }
public bool UnsubPromptOpen { get; set; }
public bool ShoppingModalOpen { get; set; }
public string IngredientUrl { get; set; }
private List<RecipeDto> relaitedRecipes;
private void ViewAuthorProfile()
{
NavManager.NavigateTo($"/PublicProfile/{recipe.Author_id}");
}
private async Task OnUnsubPromptClose(bool accepted)
{
if (accepted)
{
subscribed = false;
await Http.DeleteAsync("Subscription/DeleteSubscription/" + subscribeFromId + "/" + subscribeToId);
}
UnsubPromptOpen = false;
StateHasChanged();
}
private void OnShoppingModalClose(bool accepted)
{
ShoppingModalOpen = false;
StateHasChanged();
}
private void OpenShoppingModal(string ingredient)
{
ShoppingModalOpen = true;
IngredientUrl = "https://www.woolworths.com.au/shop/search/products?searchTerm=" + ingredient;
StateHasChanged();
}
private void OpenUnsubPrompt()
{
UnsubPromptOpen = true;
StateHasChanged();
}
private async void Subscribe()
{
subscribed = true;
SubscriptionRequestDto request = new();
request.subscribeFromId = subscribeFromId;
request.subscribeToId = subscribeToId;
await Http.PostAsJsonAsync<SubscriptionRequestDto>("Subscription", request);
return;
}
private async void Unsubscribe()
{
subscribed = false;
await Http.DeleteAsync("Subscription/DeleteSubscription/" + subscribeFromId + "/" + subscribeToId);
return;
}
protected bool CommentIsValid()
{
if (comment != "")
{
return true;
}
else
{
return false;
}
}
protected async void ClickAddComment()
{
if (!CommentIsValid()) return;
// send HTTP post request
AuthenticationState authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
if (user.Identity.IsAuthenticated)
{
string userId = user.FindFirst(c => c.Type == "sub").Value;
CreateCommentRequestDto request = new CreateCommentRequestDto();
request.Text = comment;
request.CreatedById = userId;
request.RecipeId = int.Parse(Id);
// Date time created on server side
HttpResponseMessage message = await Http.PostAsJsonAsync<CreateCommentRequestDto>("Comment", request);
recipe.Comments.Insert(0, await message.Content.ReadFromJsonAsync<CommentDto>());
StateHasChanged();
}
}
protected async void AddLike()
{
string userId = await UtilityService.GetUserId();
if (userId == null) return;
CreateLikeRequestDto request = new CreateLikeRequestDto();
request.LikedByUserId = userId;
request.RecipeId = int.Parse(Id);
await Http.PostAsJsonAsync<CreateLikeRequestDto>("Like", request);
UserHasLikedRecipe = true;
recipe.Likes++;
StateHasChanged();
}
protected async void RemoveLike()
{
string userId = await UtilityService.GetUserId();
if (userId == null) return;
await Http.DeleteAsync("Like/" + recipe.Id + "/" + userId);
UserHasLikedRecipe = false;
recipe.Likes--;
StateHasChanged();
}
protected override Task OnInitializedAsync()
{
return Load(Id);
}
protected async Task Load(string Id)
{
try
{
recipe = await Http.GetFromJsonAsync<RecipeDto>("Recipe/" + Id);
LikeInfoRequestDto requestDto = new();
string userId = await UtilityService.GetUserId();
if (userId == null) return;
requestDto.UserId = userId;
requestDto.RecipeId = int.Parse(Id);
HttpResponseMessage message = await Http.PostAsJsonAsync<LikeInfoRequestDto>("Like/GetLikeInfo", requestDto);
UserHasLikedRecipe = await message.Content.ReadFromJsonAsync<bool>();
// set subscription button details
subscribeFromId = userId;
subscribeToId = recipe.Author_id;
subscribed = await Http.GetFromJsonAsync<bool>("Subscription/CheckSubscription/" + subscribeFromId + "/" + subscribeToId);
// get realaited recipies
relaitedRecipes = await Http.GetFromJsonAsync<List<RecipeDto>>("Recipe/related/" + Id);
// get recipe author
recipeAuthor = await Http.GetFromJsonAsync<UserDto>($"PublicProfile/Data/{subscribeToId}");
}
catch (AccessTokenNotAvailableException exception)
{
exception.Redirect();
}
}
protected override async Task OnParametersSetAsync()
{
await Load(Id);
}
protected void ClickView(RecipeDto r)
{
recipe = null;
relaitedRecipes = null;
StateHasChanged();
NavManager.NavigateTo($"ViewRecipe/{r.Id}");
}
}