- реализовал личный кабинет пользователя.

- реализовал отображение заказов и отзывов по нажатию на табы в профиле пользователя.
parent 92307b0f
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
......@@ -48,8 +49,15 @@ namespace PhoneStore.Controllers
public IActionResult Create(OrderViewModel order)
{
order.UserId = int.Parse(_userManager.GetUserId(User));
_orderService.Create(order.MapToOrderViewModel());
_orderService.Create(order.MapToOrder());
return RedirectToAction("Index");
}
[HttpGet]
public IActionResult GetAllByUserId(int id)
{
var model = _orderService.GetByUserId(id).ToArray();
return Json(model);
}
}
}
\ No newline at end of file
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using PhoneStore.Mappers;
using PhoneStore.Models;
using PhoneStore.ViewModels;
namespace PhoneStore.Controllers
{
public class PersonalAreaController : Controller
{
private readonly MobileContext _db;
public PersonalAreaController(MobileContext db)
{
_db = db;
}
[HttpGet]
public IActionResult Index(int userId)
{
PersonalAreaViewModel model = new PersonalAreaViewModel
{
User = _db.Users
.FirstOrDefault(u => u.Id == userId)
.MapToUserViewModel(),
Feedbacks = _db.Feedbacks
.Include(f => f.Phone)
.Include(f => f.User)
.Where(f => f.UserId == userId).Select(f => f.MapToFeedbackViewModel())
};
return View(model);
}
}
}
\ No newline at end of file
......@@ -19,7 +19,7 @@ namespace PhoneStore.Mappers
};
}
public static Order MapToOrderViewModel(this OrderViewModel self)
public static Order MapToOrder(this OrderViewModel self)
{
return new Order
{
......@@ -27,7 +27,6 @@ namespace PhoneStore.Mappers
Phone = self.Phone?.MapToPhone(),
ContactPhone = self.ContactPhone,
PhoneId = self.PhoneId,
User = self.User?.MapToUser(),
UserId = self.UserId,
Id = self.Id
};
......
......@@ -28,7 +28,7 @@ namespace PhoneStore.Mappers
Brand = self.Brand,
Image = self.Image,
Id = self.Id,
Feedbacks = self.Feedbacks.Select(f => f.MapToFeedbackViewModel()),
Feedbacks = self.Feedbacks?.Select(f => f.MapToFeedbackViewModel()),
BrandId = self.BrandId
};
......
......@@ -7,6 +7,7 @@
<ItemGroup>
<PackageReference Include="FluentValidation" Version="11.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="5.0.17" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="5.0.17" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.17">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
......
......@@ -31,6 +31,7 @@ namespace PhoneStore.Repositories
var a =_db.Phones
.Include(p => p.Brand)
.Include(p => p.Feedbacks)
.ThenInclude(f => f.User)
.FirstOrDefault(p => p.Id == id);
return a;
}
......
namespace PhoneStore.Services.Interfaces
{
public interface IPersonalAreaServic
{
}
}
\ No newline at end of file
......@@ -21,7 +21,9 @@ namespace PhoneStore.Services
=> _orderRepository.GetAll().Select(o => o.MapToOrderViewModel());
public void Create(Order order)
=> _orderRepository.Create(order);
{
_orderRepository.Create(order);
}
public OrderViewModel GetById(int id)
=> _orderRepository.GetById(id).MapToOrderViewModel();
......
......@@ -4,6 +4,7 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json;
using PhoneStore.Helpers;
using PhoneStore.Models;
......@@ -21,16 +22,17 @@ namespace PhoneStore
public void ConfigureServices(IServiceCollection services)
{
string connection = Configuration.GetConnectionString("DefaultConnection");
services.AddDbContext<MobileContext>(options => options.UseNpgsql(connection))
.AddIdentity<User, Role>()
.AddEntityFrameworkStores<MobileContext>();
services.AddControllersWithViews();
services.AddControllersWithViews().AddNewtonsoftJson(o =>
o.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore);
//Можно так подключать сервисы
services.AddApplicationServices(Configuration);
//А можно так
RepositoryConnector.AddRepositories(services);
services.AddValidationServices();
services.AddCors();
services.AddDbContext<MobileContext>(options => options.UseNpgsql(connection))
.AddIdentity<User, Role>()
.AddEntityFrameworkStores<MobileContext>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
......@@ -51,7 +53,6 @@ namespace PhoneStore
app.UseStaticFiles();
app.UseRouting();
app.UseCors(builder => builder.AllowAnyOrigin());
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
......
using System.Collections.Generic;
using PhoneStore.ViewModels.Account;
using PhoneStore.ViewModels.Feedback;
namespace PhoneStore.ViewModels
{
public class PersonalAreaViewModel
{
public UserViewModel User { get; set; }
public IEnumerable<FeedbackViewModel> Feedbacks { get; set; }
}
}
\ No newline at end of file
......@@ -21,13 +21,7 @@ else
</tr>
@foreach (var order in Model)
{
<tr>
<td>@order.Id</td>
<td>@order.Address</td>
<td>@order.ContactPhone</td>
<td>@order.User.Name</td>
<td>@order.Phone.Name</td>
</tr>
await Html.RenderPartialAsync("PartialViews/OrderPartialView", order);
}
</table>
}
@model PersonalAreaViewModel
@{
ViewBag.Title = "title";
Layout = "_Layout";
}
<h2 userId="@Model.User.Id" >Кабинет @Model.User.Username</h2>
<div class="tabs">
<div class="tab-items row w-50 m-auto">
<a href="#tab-feedbaks" class="active tab-pane col-md-6">Все отзывы @Model.User.Username</a>
<a href="#tab-orders" class="tab-pane col-md-6">Все заказы @Model.User.Username</a>
</div>
<div class="tab-contents">
<div id="tab-feedbaks" class="tab-content">
@foreach (var feedback in Model.Feedbacks)
{
await Html.RenderPartialAsync("PartialViews/FeedbackPartialView", feedback);
}
</div>
<div id="tab-orders" class="tab-content">
<table style="width: 100%">
<thead>
<tr>
<th>Id</th>
<th>Адрес</th>
<th>Контактный телефон</th>
<th>Имя пользователя</th>
<th>Название телефона</th>
</tr>
</thead>
<tbody id="orders">
</tbody>
</table>
</div>
</div>
</div>
@section Scripts
{
<script >
$('.tab-pane').click(function (e){
e.preventDefault();
let userId = $('h2').attr('userId');
fetch("https://localhost:5001/Orders/GetAllByUserId/" + userId)
.then((response) => {
return response.json();
})
.then((orders) => {
if (orders.length === 0){
$(this).html('<h3>Заказов нет</h3>');
}
else{
let content;
$.each(orders, (order) => {
content += `<tr>
<td>order.id</td>
<td>order.address</td>
<td>order.contactPhone</td>
<td>order.user.Name</td>
<td>order.phone.Name</td>
</tr>`
});
$('#orders').html(content);
}
});
});
let makeTabs = function (){
let tabs = $(".tabs").find(".tab-items a");
$.each(tabs, function (index, item){
if ($(item).hasClass('active')){
let activeTabContent = $(this).attr('href');
$(this).parents('.tabs').find(activeTabContent).show();
}
});
$(tabs).click(function (e){
e.preventDefault();
if (!$(this).hasClass('active')){
let tabContent = $(this).attr('href');
$(this).siblings('.tab-items a').removeClass('active');
$(this).addClass('active');
$(this).closest('.tabs').find('.tab-content').hide();
$(this).closest('.tabs').find(tabContent).show();
}
});
};
makeTabs();
</script>
}
@using PhoneStore.Repositories.Interfaces
@using Microsoft.AspNetCore.Identity
@model PhoneStore.ViewModels.PhoneViewModels.PhoneViewModel
@inject IFeedbackRepository _feedbackRepository;
@inject UserManager<User> _userManager;
@{
ViewBag.Title = "Подробная информация";
Layout = "_Layout";
......@@ -14,16 +18,19 @@
</div>
@if (User.Identity.IsAuthenticated)
{
<form class="mb-3" id="feedbackForm">
<div class="form-group">
<label for="text">Добавьте отзыв о телефоне</label>
<input type="text" class="form-control" id="text" placeholder="Минимальная длина отзыва 10 символов">
<input type="text" hidden name="phoneId" id="@Model.Id">
<button class="my-3 btn btn-outline-warning" type="submit">Отправить</button>
</div>
</form>
if (!_feedbackRepository.CheckFeedbackExists(int.Parse(_userManager.GetUserId(User)), Model.Id))
{
<form class="mb-3" id="feedbackForm">
<div class="form-group">
<label for="text">Добавьте отзыв о телефоне</label>
<input type="text" class="form-control" id="text" placeholder="Минимальная длина отзыва 10 символов">
<input type="text" hidden name="phoneId" id="@Model.Id">
<button class="my-3 btn btn-outline-warning" type="submit">Отправить</button>
</div>
</form>
}
}
else
else if(!User.Identity.IsAuthenticated)
{
<a asp-action="Login" asp-controller="Account">Авторизируйтесь для добавления отзыва</a>
}
......
@using Microsoft.AspNetCore.Identity
@model PhoneStore.ViewModels.Feedback.FeedbackViewModel
@inject UserManager<User> _userManager;
@inject UserManager<User> UserManager;
<div id="@Model.Id" class="card mb-3">
<h5 class="card-header">
......@@ -13,7 +13,7 @@
<div class="card-text">@Model.Text</div>
@if (User.Identity.IsAuthenticated)
{
if (int.Parse(_userManager.GetUserId(User)) == Model.UserId)
if (int.Parse(UserManager.GetUserId(User)) == Model.UserId)
{
<button type="button"
class="btn btn-outline-warning"
......@@ -27,6 +27,5 @@
</button>
}
}
</div>
</div>
\ No newline at end of file
@model OrderViewModel
<tr>
<td>@Model.Id</td>
<td>@Model.Address</td>
<td>@Model.ContactPhone</td>
<td>@Model.User.Name</td>
<td>@Model.Phone.Name</td>
</tr>
\ No newline at end of file
<!DOCTYPE html>
@using Microsoft.AspNetCore.Identity
@inject UserManager<User> _userManager
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
......@@ -35,7 +37,10 @@
<div class="login_group">
@if(User.Identity.IsAuthenticated)
{
<p>@User.Identity.Name</p>
<a
asp-action="Index"
asp-controller="PersonalArea"
asp-route-userId="@_userManager.GetUserId(User)">@User.Identity.Name</a>
<form method="post" asp-controller="Account" asp-action="LogOff">
<button class="btn btn-outline-warning" type="submit">Выход</button>
......
......@@ -77,3 +77,37 @@ body {
.w_15 {
width: 15%;
}
.tabs{
padding: 40px 0;
}
.tab-items{
margin-bottom: -1px;
position: relative;
z-index: 10;
}
.tab-items a{
display: inline-block;
padding: 1px 25px;
border: 1px solid silver;
border-bottom: none;
background: #ccc;
color: black;
text-decoration: none;
}
.tab-items a.active{
color: lightblue;
background: #fff;
}
.tabs .tab-content{
padding: 20px;
border: 1px solid silver;
display: none;
position: relative;
z-index: 9;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment