Browse Source
* working on creating and viewing orders. * Working on wiring up listing of orders * List orders page works as expected. Needed to support ThenInclude scenarios. Currently using strings.main
committed by
GitHub
39 changed files with 698 additions and 60 deletions
@ -0,0 +1,22 @@ |
|||||
|
using Microsoft.eShopWeb.ApplicationCore.Entities; |
||||
|
|
||||
|
namespace ApplicationCore.Entities.OrderAggregate |
||||
|
{ |
||||
|
|
||||
|
public class OrderItem : BaseEntity |
||||
|
{ |
||||
|
public CatalogItemOrdered ItemOrdered { get; private set; } |
||||
|
public decimal UnitPrice { get; private set; } |
||||
|
public int Units { get; private set; } |
||||
|
|
||||
|
protected OrderItem() |
||||
|
{ |
||||
|
} |
||||
|
public OrderItem(CatalogItemOrdered itemOrdered, decimal unitPrice, int units) |
||||
|
{ |
||||
|
ItemOrdered = itemOrdered; |
||||
|
UnitPrice = unitPrice; |
||||
|
Units = units; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,12 @@ |
|||||
|
using ApplicationCore.Entities.OrderAggregate; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace ApplicationCore.Interfaces |
||||
|
{ |
||||
|
|
||||
|
public interface IOrderRepository : IRepository<Order>, IAsyncRepository<Order> |
||||
|
{ |
||||
|
Order GetByIdWithItems(int id); |
||||
|
Task<Order> GetByIdWithItemsAsync(int id); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
using ApplicationCore.Entities.OrderAggregate; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace ApplicationCore.Interfaces |
||||
|
{ |
||||
|
public interface IOrderService |
||||
|
{ |
||||
|
Task CreateOrderAsync(int basketId, Address shippingAddress); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,35 @@ |
|||||
|
using ApplicationCore.Interfaces; |
||||
|
using System; |
||||
|
using System.Linq.Expressions; |
||||
|
using System.Collections.Generic; |
||||
|
using ApplicationCore.Entities.OrderAggregate; |
||||
|
|
||||
|
namespace ApplicationCore.Specifications |
||||
|
{ |
||||
|
public class CustomerOrdersWithItemsSpecification : ISpecification<Order> |
||||
|
{ |
||||
|
private readonly string _buyerId; |
||||
|
|
||||
|
public CustomerOrdersWithItemsSpecification(string buyerId) |
||||
|
{ |
||||
|
_buyerId = buyerId; |
||||
|
AddInclude(o => o.OrderItems); |
||||
|
AddInclude("OrderItems.ItemOrdered"); |
||||
|
} |
||||
|
|
||||
|
public Expression<Func<Order, bool>> Criteria => o => o.BuyerId == _buyerId; |
||||
|
|
||||
|
public List<Expression<Func<Order, object>>> Includes { get; } = new List<Expression<Func<Order, object>>>(); |
||||
|
public List<string> IncludeStrings { get; } = new List<string>(); |
||||
|
|
||||
|
public void AddInclude(Expression<Func<Order, object>> includeExpression) |
||||
|
{ |
||||
|
Includes.Add(includeExpression); |
||||
|
} |
||||
|
|
||||
|
public void AddInclude(string includeString) |
||||
|
{ |
||||
|
IncludeStrings.Add(includeString); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,31 @@ |
|||||
|
using ApplicationCore.Entities.OrderAggregate; |
||||
|
using ApplicationCore.Interfaces; |
||||
|
using Microsoft.EntityFrameworkCore; |
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Infrastructure.Data |
||||
|
{ |
||||
|
public class OrderRepository : EfRepository<Order>, IOrderRepository |
||||
|
{ |
||||
|
public OrderRepository(CatalogContext dbContext) : base(dbContext) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public Order GetByIdWithItems(int id) |
||||
|
{ |
||||
|
return _dbContext.Orders |
||||
|
.Include(o => o.OrderItems) |
||||
|
.Include("OrderItems.ItemOrdered") |
||||
|
.FirstOrDefault(); |
||||
|
} |
||||
|
|
||||
|
public Task<Order> GetByIdWithItemsAsync(int id) |
||||
|
{ |
||||
|
return _dbContext.Orders |
||||
|
.Include(o => o.OrderItems) |
||||
|
.Include("OrderItems.ItemOrdered") |
||||
|
.FirstOrDefaultAsync(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,40 @@ |
|||||
|
using ApplicationCore.Interfaces; |
||||
|
using ApplicationCore.Entities.OrderAggregate; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.eShopWeb.ApplicationCore.Entities; |
||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
namespace Infrastructure.Services |
||||
|
{ |
||||
|
public class OrderService : IOrderService |
||||
|
{ |
||||
|
private readonly IAsyncRepository<Order> _orderRepository; |
||||
|
private readonly IAsyncRepository<Basket> _basketRepository; |
||||
|
private readonly IAsyncRepository<CatalogItem> _itemRepository; |
||||
|
|
||||
|
public OrderService(IAsyncRepository<Basket> basketRepository, |
||||
|
IAsyncRepository<CatalogItem> itemRepository, |
||||
|
IAsyncRepository<Order> orderRepository) |
||||
|
{ |
||||
|
_orderRepository = orderRepository; |
||||
|
_basketRepository = basketRepository; |
||||
|
_itemRepository = itemRepository; |
||||
|
} |
||||
|
|
||||
|
public async Task CreateOrderAsync(int basketId, Address shippingAddress) |
||||
|
{ |
||||
|
var basket = await _basketRepository.GetByIdAsync(basketId); |
||||
|
var items = new List<OrderItem>(); |
||||
|
foreach (var item in basket.Items) |
||||
|
{ |
||||
|
var catalogItem = await _itemRepository.GetByIdAsync(item.CatalogItemId); |
||||
|
var itemOrdered = new CatalogItemOrdered(catalogItem.Id, catalogItem.Name, catalogItem.PictureUri); |
||||
|
var orderItem = new OrderItem(itemOrdered, item.UnitPrice, item.Quantity); |
||||
|
items.Add(orderItem); |
||||
|
} |
||||
|
var order = new Order(basket.BuyerId, shippingAddress, items); |
||||
|
|
||||
|
await _orderRepository.AddAsync(order); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,96 @@ |
|||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.AspNetCore.Authorization; |
||||
|
using Microsoft.eShopWeb.ViewModels; |
||||
|
using System; |
||||
|
using ApplicationCore.Entities.OrderAggregate; |
||||
|
using ApplicationCore.Interfaces; |
||||
|
using System.Linq; |
||||
|
using ApplicationCore.Specifications; |
||||
|
|
||||
|
namespace Microsoft.eShopWeb.Controllers |
||||
|
{ |
||||
|
[Authorize] |
||||
|
[Route("[controller]/[action]")]
|
||||
|
public class OrderController : Controller |
||||
|
{ |
||||
|
private readonly IOrderRepository _orderRepository; |
||||
|
|
||||
|
public OrderController(IOrderRepository orderRepository) { |
||||
|
_orderRepository = orderRepository; |
||||
|
} |
||||
|
|
||||
|
public async Task<IActionResult> Index() |
||||
|
{ |
||||
|
var orders = await _orderRepository.ListAsync(new CustomerOrdersWithItemsSpecification(User.Identity.Name)); |
||||
|
|
||||
|
var viewModel = orders |
||||
|
.Select(o => new OrderViewModel() |
||||
|
{ |
||||
|
OrderDate = o.OrderDate, |
||||
|
OrderItems = o.OrderItems?.Select(oi => new OrderItemViewModel() |
||||
|
{ |
||||
|
Discount = 0, |
||||
|
PictureUrl = oi.ItemOrdered.PictureUri, |
||||
|
ProductId = oi.ItemOrdered.CatalogItemId, |
||||
|
ProductName = oi.ItemOrdered.ProductName, |
||||
|
UnitPrice = oi.UnitPrice, |
||||
|
Units = oi.Units |
||||
|
}).ToList(), |
||||
|
OrderNumber = o.Id, |
||||
|
ShippingAddress = o.ShipToAddress, |
||||
|
Status = "Pending", |
||||
|
Total = o.Total() |
||||
|
|
||||
|
}); |
||||
|
return View(viewModel); |
||||
|
} |
||||
|
|
||||
|
[HttpGet("{orderId}")] |
||||
|
public async Task<IActionResult> Detail(int orderId) |
||||
|
{ |
||||
|
var order = await _orderRepository.GetByIdWithItemsAsync(orderId); |
||||
|
var viewModel = new OrderViewModel() |
||||
|
{ |
||||
|
OrderDate = order.OrderDate, |
||||
|
OrderItems = order.OrderItems.Select(oi => new OrderItemViewModel() |
||||
|
{ |
||||
|
Discount = 0, |
||||
|
PictureUrl = oi.ItemOrdered.PictureUri, |
||||
|
ProductId = oi.ItemOrdered.CatalogItemId, |
||||
|
ProductName = oi.ItemOrdered.ProductName, |
||||
|
UnitPrice = oi.UnitPrice, |
||||
|
Units = oi.Units |
||||
|
}).ToList(), |
||||
|
OrderNumber = order.Id, |
||||
|
ShippingAddress = order.ShipToAddress, |
||||
|
Status = "Pending", |
||||
|
Total = order.Total() |
||||
|
}; |
||||
|
return View(viewModel); |
||||
|
} |
||||
|
|
||||
|
private OrderViewModel GetOrder() |
||||
|
{ |
||||
|
var order = new OrderViewModel() |
||||
|
{ |
||||
|
OrderDate = DateTimeOffset.Now.AddDays(-1), |
||||
|
OrderNumber = 12354, |
||||
|
Status = "Submitted", |
||||
|
Total = 123.45m, |
||||
|
ShippingAddress = new Address("123 Main St.", "Kent", "OH", "United States", "44240") |
||||
|
}; |
||||
|
|
||||
|
order.OrderItems.Add(new OrderItemViewModel() |
||||
|
{ |
||||
|
ProductId = 1, |
||||
|
PictureUrl = "", |
||||
|
ProductName = "Something", |
||||
|
UnitPrice = 5.05m, |
||||
|
Units = 2 |
||||
|
}); |
||||
|
|
||||
|
return order; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.ComponentModel.DataAnnotations; |
||||
|
|
||||
|
namespace Microsoft.eShopWeb.ViewModels |
||||
|
{ |
||||
|
|
||||
|
public class OrderItemViewModel |
||||
|
{ |
||||
|
public int ProductId { get; set; } |
||||
|
|
||||
|
public string ProductName { get; set; } |
||||
|
|
||||
|
public decimal UnitPrice { get; set; } |
||||
|
|
||||
|
public decimal Discount { get; set; } |
||||
|
|
||||
|
public int Units { get; set; } |
||||
|
|
||||
|
public string PictureUrl { get; set; } |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,21 @@ |
|||||
|
using ApplicationCore.Entities.OrderAggregate; |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
namespace Microsoft.eShopWeb.ViewModels |
||||
|
{ |
||||
|
|
||||
|
public class OrderViewModel |
||||
|
{ |
||||
|
public int OrderNumber { get; set; } |
||||
|
public DateTimeOffset OrderDate { get; set; } |
||||
|
public decimal Total { get; set; } |
||||
|
public string Status { get; set; } |
||||
|
|
||||
|
public Address ShippingAddress { get; set; } |
||||
|
|
||||
|
public List<OrderItemViewModel> OrderItems { get; set; } = new List<OrderItemViewModel>(); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,88 @@ |
|||||
|
@using Microsoft.eShopWeb.ViewModels |
||||
|
@model OrderViewModel |
||||
|
@{ |
||||
|
ViewData["Title"] = "My Order History"; |
||||
|
} |
||||
|
@{ |
||||
|
ViewData["Title"] = "Order Detail"; |
||||
|
} |
||||
|
|
||||
|
<div class="esh-orders_detail"> |
||||
|
<div class="container"> |
||||
|
<section class="esh-orders_detail-section"> |
||||
|
<article class="esh-orders_detail-titles row"> |
||||
|
<section class="esh-orders_detail-title col-xs-3">Order number</section> |
||||
|
<section class="esh-orders_detail-title col-xs-3">Date</section> |
||||
|
<section class="esh-orders_detail-title col-xs-3">Total</section> |
||||
|
<section class="esh-orders_detail-title col-xs-3">Status</section> |
||||
|
</article> |
||||
|
|
||||
|
<article class="esh-orders_detail-items row"> |
||||
|
<section class="esh-orders_detail-item col-xs-3">@Model.OrderNumber</section> |
||||
|
<section class="esh-orders_detail-item col-xs-3">@Model.OrderDate</section> |
||||
|
<section class="esh-orders_detail-item col-xs-3">$@Model.Total</section> |
||||
|
<section class="esh-orders_detail-title col-xs-3">@Model.Status</section> |
||||
|
</article> |
||||
|
</section> |
||||
|
|
||||
|
@*<section class="esh-orders_detail-section"> |
||||
|
<article class="esh-orders_detail-titles row"> |
||||
|
<section class="esh-orders_detail-title col-xs-12">Description</section> |
||||
|
</article> |
||||
|
|
||||
|
<article class="esh-orders_detail-items row"> |
||||
|
<section class="esh-orders_detail-item col-xs-12">@Model.Description</section> |
||||
|
</article> |
||||
|
</section>*@ |
||||
|
|
||||
|
<section class="esh-orders_detail-section"> |
||||
|
<article class="esh-orders_detail-titles row"> |
||||
|
<section class="esh-orders_detail-title col-xs-12">Shipping Address</section> |
||||
|
</article> |
||||
|
|
||||
|
<article class="esh-orders_detail-items row"> |
||||
|
<section class="esh-orders_detail-item col-xs-12">@Model.ShippingAddress.Street</section> |
||||
|
</article> |
||||
|
|
||||
|
<article class="esh-orders_detail-items row"> |
||||
|
<section class="esh-orders_detail-item col-xs-12">@Model.ShippingAddress.City</section> |
||||
|
</article> |
||||
|
|
||||
|
<article class="esh-orders_detail-items row"> |
||||
|
<section class="esh-orders_detail-item col-xs-12">@Model.ShippingAddress.Country</section> |
||||
|
</article> |
||||
|
</section> |
||||
|
|
||||
|
<section class="esh-orders_detail-section"> |
||||
|
<article class="esh-orders_detail-titles row"> |
||||
|
<section class="esh-orders_detail-title col-xs-12">ORDER DETAILS</section> |
||||
|
</article> |
||||
|
|
||||
|
@for (int i = 0; i < Model.OrderItems.Count; i++) |
||||
|
{ |
||||
|
var item = Model.OrderItems[i]; |
||||
|
<article class="esh-orders_detail-items esh-orders_detail-items--border row"> |
||||
|
<section class="esh-orders_detail-item col-md-4 hidden-md-down"> |
||||
|
<img class="esh-orders_detail-image" src="@item.PictureUrl"> |
||||
|
</section> |
||||
|
<section class="esh-orders_detail-item esh-orders_detail-item--middle col-xs-4">@item.ProductName</section> |
||||
|
<section class="esh-orders_detail-item esh-orders_detail-item--middle col-xs-1">$ @item.UnitPrice.ToString("N2")</section> |
||||
|
<section class="esh-orders_detail-item esh-orders_detail-item--middle col-xs-1">@item.Units</section> |
||||
|
<section class="esh-orders_detail-item esh-orders_detail-item--middle col-xs-2">$ @Math.Round(item.Units * item.UnitPrice, 2).ToString("N2")</section> |
||||
|
</article> |
||||
|
} |
||||
|
</section> |
||||
|
|
||||
|
<section class="esh-orders_detail-section esh-orders_detail-section--right"> |
||||
|
<article class="esh-orders_detail-titles esh-basket-titles--clean row"> |
||||
|
<section class="esh-orders_detail-title col-xs-9"></section> |
||||
|
<section class="esh-orders_detail-title col-xs-2">TOTAL</section> |
||||
|
</article> |
||||
|
|
||||
|
<article class="esh-orders_detail-items row"> |
||||
|
<section class="esh-orders_detail-item col-xs-9"></section> |
||||
|
<section class="esh-orders_detail-item esh-orders_detail-item--mark col-xs-2">$ @Model.Total</section> |
||||
|
</article> |
||||
|
</section> |
||||
|
</div> |
||||
|
</div> |
||||
@ -0,0 +1,39 @@ |
|||||
|
@using Microsoft.eShopWeb.ViewModels |
||||
|
@model IEnumerable<OrderViewModel> |
||||
|
@{ |
||||
|
ViewData["Title"] = "My Order History"; |
||||
|
} |
||||
|
|
||||
|
<div class="esh-orders"> |
||||
|
<div class="container"> |
||||
|
<h1>@ViewData["Title"]</h1> |
||||
|
<article class="esh-orders-titles row"> |
||||
|
<section class="esh-orders-title col-xs-2">Order number</section> |
||||
|
<section class="esh-orders-title col-xs-4">Date</section> |
||||
|
<section class="esh-orders-title col-xs-2">Total</section> |
||||
|
<section class="esh-orders-title col-xs-2">Status</section> |
||||
|
<section class="esh-orders-title col-xs-2"></section> |
||||
|
</article> |
||||
|
@if (Model != null && Model.Any()) |
||||
|
{ |
||||
|
@foreach (var item in Model) |
||||
|
{ |
||||
|
<article class="esh-orders-items row"> |
||||
|
<section class="esh-orders-item col-xs-2">@Html.DisplayFor(modelItem => item.OrderNumber)</section> |
||||
|
<section class="esh-orders-item col-xs-4">@Html.DisplayFor(modelItem => item.OrderDate)</section> |
||||
|
<section class="esh-orders-item col-xs-2">$ @Html.DisplayFor(modelItem => item.Total)</section> |
||||
|
<section class="esh-orders-item col-xs-2">@Html.DisplayFor(modelItem => item.Status)</section> |
||||
|
<section class="esh-orders-item col-xs-1"> |
||||
|
<a class="esh-orders-link" asp-controller="Order" asp-action="Detail" asp-route-orderId="@item.OrderNumber">Detail</a> |
||||
|
</section> |
||||
|
<section class="esh-orders-item col-xs-1"> |
||||
|
@if (item.Status.ToLower() == "submitted") |
||||
|
{ |
||||
|
<a class="esh-orders-link" asp-controller="Order" asp-action="cancel" asp-route-orderId="@item.OrderNumber">Cancel</a> |
||||
|
} |
||||
|
</section> |
||||
|
</article> |
||||
|
} |
||||
|
} |
||||
|
</div> |
||||
|
</div> |
||||
@ -0,0 +1,50 @@ |
|||||
|
.esh-orders { |
||||
|
min-height: 80vh; |
||||
|
overflow-x: hidden; } |
||||
|
.esh-orders-header { |
||||
|
background-color: #00A69C; |
||||
|
height: 4rem; } |
||||
|
.esh-orders-back { |
||||
|
color: rgba(255, 255, 255, 0.4); |
||||
|
line-height: 4rem; |
||||
|
text-decoration: none; |
||||
|
text-transform: uppercase; |
||||
|
transition: color 0.35s; } |
||||
|
.esh-orders-back:hover { |
||||
|
color: #FFFFFF; |
||||
|
transition: color 0.35s; } |
||||
|
.esh-orders-titles { |
||||
|
padding-bottom: 1rem; |
||||
|
padding-top: 2rem; } |
||||
|
.esh-orders-title { |
||||
|
text-transform: uppercase; } |
||||
|
.esh-orders-items { |
||||
|
height: 2rem; |
||||
|
line-height: 2rem; |
||||
|
position: relative; } |
||||
|
.esh-orders-items:nth-of-type(2n + 1):before { |
||||
|
background-color: #EEEEFF; |
||||
|
content: ''; |
||||
|
height: 100%; |
||||
|
left: 0; |
||||
|
margin-left: -100vw; |
||||
|
position: absolute; |
||||
|
top: 0; |
||||
|
width: 200vw; |
||||
|
z-index: -1; } |
||||
|
.esh-orders-item { |
||||
|
font-weight: 300; } |
||||
|
.esh-orders-item--hover { |
||||
|
opacity: 0; |
||||
|
pointer-events: none; } |
||||
|
.esh-orders-items:hover .esh-orders-item--hover { |
||||
|
opacity: 1; |
||||
|
pointer-events: all; } |
||||
|
.esh-orders-link { |
||||
|
color: #83D01B; |
||||
|
text-decoration: none; |
||||
|
transition: color 0.35s; } |
||||
|
.esh-orders-link:hover { |
||||
|
color: #75b918; |
||||
|
transition: color 0.35s; } |
||||
|
|
||||
@ -0,0 +1 @@ |
|||||
|
.esh-orders{min-height:80vh;overflow-x:hidden}.esh-orders-header{background-color:#00a69c;height:4rem}.esh-orders-back{color:rgba(255,255,255,.4);line-height:4rem;text-decoration:none;text-transform:uppercase;transition:color .35s}.esh-orders-back:hover{color:#fff;transition:color .35s}.esh-orders-titles{padding-bottom:1rem;padding-top:2rem}.esh-orders-title{text-transform:uppercase}.esh-orders-items{height:2rem;line-height:2rem;position:relative}.esh-orders-items:nth-of-type(2n+1):before{background-color:#eef;content:'';height:100%;left:0;margin-left:-100vw;position:absolute;top:0;width:200vw;z-index:-1}.esh-orders-item{font-weight:300}.esh-orders-item--hover{opacity:0;pointer-events:none}.esh-orders-items:hover .esh-orders-item--hover{opacity:1;pointer-events:all}.esh-orders-link{color:#83d01b;text-decoration:none;transition:color .35s}.esh-orders-link:hover{color:#75b918;transition:color .35s} |
||||
@ -0,0 +1,91 @@ |
|||||
|
@import '../variables'; |
||||
|
|
||||
|
.esh-orders { |
||||
|
min-height: 80vh; |
||||
|
overflow-x: hidden; |
||||
|
$header-height: 4rem; |
||||
|
&-header |
||||
|
|
||||
|
{ |
||||
|
background-color: #00A69C; |
||||
|
height: $header-height; |
||||
|
} |
||||
|
|
||||
|
&-back { |
||||
|
color: rgba($color-foreground-brighter, .4); |
||||
|
line-height: $header-height; |
||||
|
text-decoration: none; |
||||
|
text-transform: uppercase; |
||||
|
transition: color $animation-speed-default; |
||||
|
&:hover |
||||
|
|
||||
|
{ |
||||
|
color: $color-foreground-brighter; |
||||
|
transition: color $animation-speed-default; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
&-titles { |
||||
|
padding-bottom: 1rem; |
||||
|
padding-top: 2rem; |
||||
|
} |
||||
|
|
||||
|
&-title { |
||||
|
text-transform: uppercase; |
||||
|
} |
||||
|
|
||||
|
&-items { |
||||
|
$height: 2rem; |
||||
|
height: $height; |
||||
|
line-height: $height; |
||||
|
position: relative; |
||||
|
&:nth-of-type(2n + 1) |
||||
|
|
||||
|
{ |
||||
|
&:before |
||||
|
|
||||
|
{ |
||||
|
background-color: $color-background-bright; |
||||
|
content: ''; |
||||
|
height: 100%; |
||||
|
left: 0; |
||||
|
margin-left: -100vw; |
||||
|
position: absolute; |
||||
|
top: 0; |
||||
|
width: 200vw; |
||||
|
z-index: -1; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
&-item { |
||||
|
font-weight: $font-weight-semilight; |
||||
|
&--hover |
||||
|
|
||||
|
{ |
||||
|
opacity: 0; |
||||
|
pointer-events: none; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
&-items:hover &-item--hover { |
||||
|
opacity: 1; |
||||
|
pointer-events: all; |
||||
|
} |
||||
|
|
||||
|
&-link { |
||||
|
color: $color-secondary; |
||||
|
text-decoration: none; |
||||
|
transition: color $animation-speed-default; |
||||
|
&:hover |
||||
|
|
||||
|
{ |
||||
|
color: $color-secondary-dark; |
||||
|
transition: color $animation-speed-default; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
Before Width: | Height: | Size: 5.1 KiB |
Loading…
Reference in new issue