Skip to content
This repository has been archived by the owner on Jul 12, 2024. It is now read-only.

Commit

Permalink
style: add feature products
Browse files Browse the repository at this point in the history
  • Loading branch information
foxminchan committed Jun 2, 2024
1 parent 326a87e commit 4d6d5b4
Show file tree
Hide file tree
Showing 12 changed files with 144 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ public async Task<Result<IEnumerable<BestSellerProductsDto>>> Handle(BestSellerP
FROM products p
JOIN order_details od ON p.id = od.product_id
JOIN orders o ON od.order_id = o.id
WHERE o.order_status = 1
WHERE o.order_status = 1
AND p.status = 1
AND p.is_deleted = false
GROUP BY p.id, p.name, p.image_name, p.price
ORDER BY {nameof(BestSellerProductsDto.TotalSoldQuantity)} DESC
LIMIT 5
Expand Down
7 changes: 7 additions & 0 deletions ui/storefront/Areas/Product/Models/Products/ProductPrice.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace RookieShop.Storefront.Areas.Product.Models.Products;

public sealed class ProductPrice
{
public decimal Price { get; set; }
public decimal? PriceSale { get; set; }
}
4 changes: 3 additions & 1 deletion ui/storefront/Configurations/ConfigureHttpServices.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using RookieShop.Storefront.Areas.Product.Services;
using RookieShop.Storefront.Areas.User.Services;
using RookieShop.Storefront.Delegates;
using RookieShop.Storefront.Services;

namespace RookieShop.Storefront.Configurations;

Expand All @@ -26,7 +27,8 @@ public static IHostApplicationBuilder AddHttpServices(this IHostApplicationBuild
typeof(IFeedbackService),
typeof(IBasketService),
typeof(ICustomerService),
typeof(IOrderService)
typeof(IOrderService),
typeof(IReportService)
];

foreach (var type in types)
Expand Down
15 changes: 15 additions & 0 deletions ui/storefront/Models/Report/BestSellerProduct.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System.Text.Json.Serialization;

namespace RookieShop.Storefront.Models.Report;

public class BestSellerProduct
{
[JsonPropertyName("productId")] public Guid ProductId { get; set; }

[JsonPropertyName("productName")] public string? ProductName { get; set; }

[JsonPropertyName("totalSoldQuantity")]
public int TotalSoldQuantity { get; set; }

[JsonPropertyName("imageUrl")] public string? ImageUrl { get; set; }
}
8 changes: 8 additions & 0 deletions ui/storefront/Models/Report/BestSellerProductFilterParams.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Refit;

namespace RookieShop.Storefront.Models.Report;

public sealed class BestSellerProductFilterParams
{
[AliasAs("top")] public int Top { get; set; } = 4;
}
9 changes: 9 additions & 0 deletions ui/storefront/Models/Report/BestSellerProductResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System.Text.Json.Serialization;

namespace RookieShop.Storefront.Models.Report;

public sealed class BestSellerProductResponse : BestSellerProduct
{
[JsonPropertyName("price")]
public string Price { get; set; } = string.Empty;
}
8 changes: 8 additions & 0 deletions ui/storefront/Models/Report/BestSellerProductViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using RookieShop.Storefront.Areas.Product.Models.Products;

namespace RookieShop.Storefront.Models.Report;

public sealed class BestSellerProductViewModel : BestSellerProduct
{
public ProductPrice? Price { get; set; }
}
10 changes: 10 additions & 0 deletions ui/storefront/Services/IReportService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Refit;
using RookieShop.Storefront.Models.Report;

namespace RookieShop.Storefront.Services;

public interface IReportService
{
[Get("/reports/best-seller-products")]
Task <List<BestSellerProductResponse>> GetBestSellerProductsAsync([Query] BestSellerProductFilterParams filterParams);
}
9 changes: 9 additions & 0 deletions ui/storefront/Views/Home/Index.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@

<partial name="Partials/Home/_HeroPartial"/>
<hr/>
<div class="bg-white">
<div class="mx-auto max-w-2xl px-4 py-16 sm:px-6 lg:max-w-7xl lg:px-8">
<h1 class="text-2xl font-bold tracking-tight text-gray-900 text-center">Feature Product</h1>
<div class="mt-6 grid grid-cols-1 gap-x-6 gap-y-10 sm:grid-cols-2 lg:grid-cols-4 xl:gap-x-8">
@await Component.InvokeAsync("FeatureProducts")
</div>
</div>
</div>
<hr />
<partial name="Partials/Home/_StatsPartial"/>
<hr/>
<partial name="Partials/Home/_BenefitPartial"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
@model List<RookieShop.Storefront.Models.Report.BestSellerProductViewModel>

@if (Model.Count == 0)
{
<div class="text-center text-red-500">
<strong>Warning!</strong> There are no products to show.
</div>
}
else
{
@foreach (var item in Model)
{
<div class="group relative">
<div class="aspect-h-1 aspect-w-1 w-full overflow-hidden rounded-md bg-gray-200 lg:aspect-none group-hover:opacity-75">
<img loading="lazy"
src="@(item.ImageUrl ?? "~/imgs/product/default-preview-image.png")"
alt="@item.ProductName"
class="h-full w-full"
asp-append-version="true" />
</div>
<div class="mt-4 flex justify-between">
<div>
<h3 class="text-sm text-gray-700">
<span class="font-medium hover:text-gray-800">
<span aria-hidden="true" class="absolute inset-0"></span>
@item.ProductName
</span>
</h3>
</div>
<a asp-area="Product"
asp-controller="Product"
asp-action="Detail"
asp-route-id="@item.ProductId"
class="text-sm font-medium text-gray-900 text-red-900">
Purchase
</a>
</div>
</div>
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System.Text.Json;
using Microsoft.AspNetCore.Mvc;
using RookieShop.Storefront.Areas.Product.Models.Products;
using RookieShop.Storefront.Models.Report;
using RookieShop.Storefront.Services;

namespace RookieShop.Storefront.Views.Shared.Components.FeatureProducts;

[ViewComponent]
public sealed class FeatureProductsViewComponent(IReportService reportService) : ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync()
{
var data = await reportService.GetBestSellerProductsAsync(new());

var result = data.Select(x => new BestSellerProductViewModel
{
ProductId = x.ProductId,
ProductName = x.ProductName,
TotalSoldQuantity = x.TotalSoldQuantity,
Price = JsonSerializer.Deserialize<ProductPrice>(x.Price),
ImageUrl = x.ImageUrl
}).ToList();

return View(result);
}
}
5 changes: 5 additions & 0 deletions ui/storefront/wwwroot/css/output.css
Original file line number Diff line number Diff line change
Expand Up @@ -2078,6 +2078,11 @@ video {
color: rgb(107 114 128 / var(--tw-text-opacity));
}

.hover\:text-gray-800:hover {
--tw-text-opacity: 1;
color: rgb(31 41 55 / var(--tw-text-opacity));
}

.hover\:text-gray-900:hover {
--tw-text-opacity: 1;
color: rgb(17 24 39 / var(--tw-text-opacity));
Expand Down

0 comments on commit 4d6d5b4

Please sign in to comment.