Spaces:
Sleeping
Sleeping
File size: 6,943 Bytes
6db0915 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 | using ECommerce.Model.Data;
using ECommerce.Model.Entities;
using ECommerce.Model.Repositories;
using ECommerce.Presenter.Presenters;
using ECommerce.Presenter.ViewModels;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace Ecommerce_web_project.Controllers;
public class HomeController : Controller
{
private readonly ProductListPresenter _presenter;
private readonly ReviewPresenter _reviewPresenter;
private readonly IRepository<Product> _productRepo;
private readonly UserManager<IdentityUser> _userManager;
private readonly IEmailSender _emailSender;
private readonly AppDbContext _context;
public HomeController(ProductListPresenter presenter, ReviewPresenter reviewPresenter, IRepository<Product> productRepo, UserManager<IdentityUser> userManager, IEmailSender emailSender, AppDbContext context)
{
_presenter = presenter;
_reviewPresenter = reviewPresenter;
_productRepo = productRepo;
_userManager = userManager;
_emailSender = emailSender;
_context = context;
}
public async Task<IActionResult> Index(Guid? categoryId, string? search)
{
var model = await _presenter.GetProductListAsync(search, categoryId);
var allProducts = await _context.Products.Include(p => p.Category).ToListAsync();
var allProductIds = allProducts.Select(p => p.Id).ToList();
var allReviews = await _context.Reviews.Where(r => allProductIds.Contains(r.ProductId)).ToListAsync();
var ratingLookup = allReviews.GroupBy(r => r.ProductId).ToDictionary(g => g.Key, g => g.Average(r => (double)r.Rating));
var countLookup = allReviews.GroupBy(r => r.ProductId).ToDictionary(g => g.Key, g => g.Count());
ViewBag.NewArrivals = allProducts
.OrderByDescending(p => p.CreatedAt)
.Take(5)
.Select(p => new ProductViewModel
{
Id = p.Id,
Name = p.Name,
Description = p.Description,
Price = p.Price,
ImageUrl = p.ImageUrl,
StockQuantity = p.StockQuantity,
CategoryName = p.Category.Name,
CategoryId = p.CategoryId,
AverageRating = ratingLookup.GetValueOrDefault(p.Id, 0),
ReviewCount = countLookup.GetValueOrDefault(p.Id, 0)
}).ToList();
var salesData = await _context.OrderItems
.GroupBy(oi => oi.ProductId)
.Select(g => new { ProductId = g.Key, TotalSold = g.Sum(oi => oi.Quantity) })
.ToListAsync();
var bestSellerIds = salesData
.OrderByDescending(s => s.TotalSold)
.Take(5)
.Select(s => s.ProductId)
.ToHashSet();
ViewBag.BestSellers = allProducts
.Where(p => bestSellerIds.Contains(p.Id))
.OrderByDescending(p => bestSellerIds.Contains(p.Id) ? salesData.First(s => s.ProductId == p.Id).TotalSold : 0)
.Take(5)
.Select(p => new ProductViewModel
{
Id = p.Id,
Name = p.Name,
Description = p.Description,
Price = p.Price,
ImageUrl = p.ImageUrl,
StockQuantity = p.StockQuantity,
CategoryName = p.Category.Name,
CategoryId = p.CategoryId,
AverageRating = ratingLookup.GetValueOrDefault(p.Id, 0),
ReviewCount = countLookup.GetValueOrDefault(p.Id, 0)
}).ToList();
if (ViewBag.BestSellers.Count == 0)
{
ViewBag.BestSellers = allProducts
.OrderByDescending(p => p.CreatedAt)
.Take(5)
.Select(p => new ProductViewModel
{
Id = p.Id,
Name = p.Name,
Description = p.Description,
Price = p.Price,
ImageUrl = p.ImageUrl,
StockQuantity = p.StockQuantity,
CategoryName = p.Category.Name,
CategoryId = p.CategoryId,
AverageRating = ratingLookup.GetValueOrDefault(p.Id, 0),
ReviewCount = countLookup.GetValueOrDefault(p.Id, 0)
}).ToList();
}
ViewBag.RecentReviews = await _reviewPresenter.GetRecentReviewsAsync(6);
return View(model);
}
public async Task<IActionResult> Shop(Guid? categoryId, string? search, string? sortBy, int page = 1)
{
var model = await _presenter.GetProductListAsync(search, categoryId, sortBy, page, 10);
return View("Shop", model);
}
public async Task<IActionResult> Details(Guid id)
{
var product = await _presenter.GetProductByIdAsync(id);
if (product is null) return NotFound();
var reviews = await _reviewPresenter.GetReviewsAsync(id);
product.AverageRating = reviews.Any() ? reviews.Average(r => r.Rating) : 0;
product.ReviewCount = reviews.Count;
ViewBag.Reviews = reviews;
return View(product);
}
[HttpPost]
[Authorize]
public async Task<IActionResult> AddReview(ReviewRequest request)
{
var product = await _productRepo.GetByIdAsync(request.ProductId);
if (product is null) return NotFound();
var user = await _userManager.GetUserAsync(User);
await _reviewPresenter.AddReviewAsync(request, user!.Id, user.Email ?? "Anonymous");
TempData["ReviewSuccess"] = "Review submitted!";
return RedirectToAction("Details", new { id = request.ProductId });
}
public IActionResult Privacy() => View();
public IActionResult Faq() => View();
[HttpGet]
public IActionResult Contact() => View();
[HttpPost]
public async Task<IActionResult> Contact(string name, string email, string message)
{
if (string.IsNullOrWhiteSpace(name) || string.IsNullOrWhiteSpace(email) || string.IsNullOrWhiteSpace(message))
{
ModelState.AddModelError("", "All fields are required.");
return View();
}
var body = $"""
<h2>New Contact Message</h2>
<p><strong>Name:</strong> {name}</p>
<p><strong>Email:</strong> {email}</p>
<p><strong>Message:</strong></p>
<p>{message}</p>
""";
try
{
await _emailSender.SendEmailAsync("danishnaseer000@gmail.com", $"Contact Form — {name}", body);
TempData["Success"] = "Message sent! We'll get back to you soon.";
}
catch
{
ModelState.AddModelError("", "Failed to send message. Please try again.");
return View();
}
return RedirectToAction("Contact");
}
}
|