From 10f3e17b55c6826e45e8ff81e882a65df265d083 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Ca=C3=B1izares=20Est=C3=A9vez?= Date: Mon, 19 Dec 2016 10:20:02 +0100 Subject: [PATCH] Add Swagger to Basket Api SQL databases with the same prefix for services Move application tier to api tier in ordering api --- docker-compose.override.yml | 43 +++---- docker-compose.yml | 20 +-- .../Basket.API/Controllers/HomeController.cs | 19 +++ src/Services/Basket/Basket.API/Startup.cs | 20 ++- src/Services/Basket/Basket.API/project.json | 3 +- .../Catalog/Catalog.API/settings.json | 2 +- .../eShopOnContainers.Identity/AppSettings.cs | 12 ++ .../Configuration/Config.cs | 2 +- .../Controllers/AccountController.cs | 18 +-- .../Controllers/HomeController.cs | 11 +- .../eShopOnContainers.Identity/Startup.cs | 4 +- .../Views/Shared/_Layout.cshtml | 14 --- .../appsettings.json | 2 +- .../docker-compose.yml | 4 +- .../Application/Commands/NewOrderRequest.cs | 48 +++++++ .../Commands/NewOrderRequestHandler.cs | 118 ++++++++++++++++++ .../Application/Decorators/LogDecorator.cs | 34 +++++ .../Application/Queries/IOrderQueries.cs | 13 ++ .../Application/Queries/OrderQueries.cs | 101 +++++++++++++++ .../Controllers/OrdersController.cs | 6 +- .../AutofacModules/ApplicationModule.cs | 2 +- .../AutofacModules/MediatorModule.cs | 4 +- .../Ordering/Ordering.API/project.json | 6 +- src/Web/WebMVC/Services/OrderingService.cs | 2 +- src/Web/WebMVC/wwwroot/css/site.min.css | 2 +- .../eShopOnContainers.WebSPA/Program.cs | 2 +- 26 files changed, 429 insertions(+), 83 deletions(-) create mode 100644 src/Services/Basket/Basket.API/Controllers/HomeController.cs create mode 100644 src/Services/Identity/eShopOnContainers.Identity/AppSettings.cs create mode 100644 src/Services/Ordering/Ordering.API/Application/Commands/NewOrderRequest.cs create mode 100644 src/Services/Ordering/Ordering.API/Application/Commands/NewOrderRequestHandler.cs create mode 100644 src/Services/Ordering/Ordering.API/Application/Decorators/LogDecorator.cs create mode 100644 src/Services/Ordering/Ordering.API/Application/Queries/IOrderQueries.cs create mode 100644 src/Services/Ordering/Ordering.API/Application/Queries/OrderQueries.cs diff --git a/docker-compose.override.yml b/docker-compose.override.yml index 4dfa4dc63..285194cd6 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -9,21 +9,22 @@ version: '2' services: -# webmvc: -# environment: -# - CatalogUrl=http://catalog.api -# - OrderingUrl=http://ordering.api:5102 - #- IdentityUrl=http://104.40.62.65:5105 #Remote: VM Needs to have public access at 5105. -# - IdentityUrl=http://identity.service:5105 #Local: You need a entry in windows host file to run identity in local docker. -# - BasketUrl=http://basket.api:5103 -# ports: -# - "5100:5100" + webmvc: + environment: + - CatalogUrl=http://catalog.api + - OrderingUrl=http://ordering.api:5102 + #- IdentityUrl=http://13.88.8.119:5105 #Remote: VM Needs to have public access at 5105. + #- IdentityUrl=http://10.0.75.1:5105 #Local: You need to open windows firewall at range 5100-5105. + - IdentityUrl=http://identity.service:5105 #Local: You need a entry in windows host file to run identity in local docker. + - BasketUrl=http://basket.api:5103 + ports: + - "5100:5100" webspa: environment: - CatalogUrl=http://catalog.api - OrderingUrl=http://ordering.api - #- IdentityUrl=http://104.40.62.65:5105 #Remote: VM Needs to have public access at 5105. + #- IdentityUrl=http://13.88.8.119:5105 #Remote: VM Needs to have public access at 5105. - IdentityUrl=http://identity.service:5105 #Local: You need a entry in windows host file to run identity in local docker. - BasketUrl=http://basket.api:5103 ports: @@ -32,30 +33,30 @@ services: basket.api: environment: - ConnectionString=basket.data - #- identityUrl=http://104.40.62.65:5105 #Remote: VM Needs to have public access at 5105. + #- identityUrl=http://13.88.8.119:5105 #Remote - identityUrl=http://identity.service:5105 #Local: You need a entry in windows host file to run identity in local docker. ports: - "5103:5103" catalog.api: environment: - - ConnectionString=Server=sql.data;Database=CatalogDB;User Id=sa;Password=Pass@word + - ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word ports: - "5101:80" -# ordering.api: -# environment: -# - ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word -# - identityUrl=http://identity.service:5105 #local - #- identityUrl=http://104.40.62.65:5105 #remote -# ports: -# - "5102:5102" + ordering.api: + environment: + - ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word + - identityUrl=http://identity.service:5105 #local + #- identityUrl=http://13.88.8.119:5105 #remote + ports: + - "5102:5102" identity.service: environment: - SpaClient=http://localhost:5104 - - ConnectionStrings__DefaultConnection=Server=sql.data;Database=aspnet-Microsoft.eShopOnContainers;User Id=sa;Password=Pass@word - #- MvcClient=http://104.40.62.65:5100 #Remote: VM Needs to have public access at 5105. + - ConnectionStrings__DefaultConnection=Server=sql.data;Database=Microsoft.eShopOnContainers.Service.IdentityDb;User Id=sa;Password=Pass@word + #- MvcClient=http://13.88.8.119:5100 #Remote: VM Needs to have public access at 5105. - MvcClient=http://localhost:5100 #Local: You need a entry in windows host file to run identity in local docker. #10.0.75.1:5105 CCE/TODO: try to avoid host entry. ports: diff --git a/docker-compose.yml b/docker-compose.yml index c8dc1797f..030db7df0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,11 +7,13 @@ version: '2' services: -# webmvc: -# image: eshop/web -# depends_on: -# - identity.service -# - basket.api + webmvc: + image: eshop/web + links: + - identity.service:localhost + depends_on: + - identity.service + - basket.api webspa: image: eshop/webspa @@ -30,10 +32,10 @@ services: depends_on: - sql.data -# ordering.api: -# image: eshop/ordering.api -# depends_on: -# - sql.data + ordering.api: + image: eshop/ordering.api + depends_on: + - sql.data identity.service: image: eshop/identity diff --git a/src/Services/Basket/Basket.API/Controllers/HomeController.cs b/src/Services/Basket/Basket.API/Controllers/HomeController.cs new file mode 100644 index 000000000..5cf7ab855 --- /dev/null +++ b/src/Services/Basket/Basket.API/Controllers/HomeController.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; + +// For more information on enabling MVC for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860 + +namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers +{ + public class HomeController : Controller + { + // GET: // + public IActionResult Index() + { + return new RedirectResult("~/swagger/ui"); + } + } +} diff --git a/src/Services/Basket/Basket.API/Startup.cs b/src/Services/Basket/Basket.API/Startup.cs index ef7eeebf3..ee804948e 100644 --- a/src/Services/Basket/Basket.API/Startup.cs +++ b/src/Services/Basket/Basket.API/Startup.cs @@ -47,6 +47,20 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API return ConnectionMultiplexer.Connect(ips.First().ToString()); }); + services.AddSwaggerGen(); + services.ConfigureSwaggerGen(options => + { + options.DescribeAllEnumsAsStrings(); + options.SingleApiVersion(new Swashbuckle.Swagger.Model.Info() + { + Title = "Basket HTTP API", + Version = "v1", + Description = "The Basket Service HTTP API", + TermsOfService = "Terms Of Service" + }); + }); + + services.AddCors(options => { options.AddPolicy("CorsPolicy", @@ -77,7 +91,11 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API RequireHttpsMetadata = false }); - app.UseMvc(); + app.UseMvcWithDefaultRoute(); + + app.UseSwagger() + .UseSwaggerUi(); + } } } diff --git a/src/Services/Basket/Basket.API/project.json b/src/Services/Basket/Basket.API/project.json index fe432c0d3..bff91d429 100644 --- a/src/Services/Basket/Basket.API/project.json +++ b/src/Services/Basket/Basket.API/project.json @@ -17,7 +17,8 @@ "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0", "StackExchange.Redis": "1.1.608", "Newtonsoft.Json": "9.0.1", - "IdentityServer4.AccessTokenValidation": "1.0.1-rc3" + "IdentityServer4.AccessTokenValidation": "1.0.1-rc3", + "Swashbuckle": "6.0.0-beta902" }, "tools": { "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final" diff --git a/src/Services/Catalog/Catalog.API/settings.json b/src/Services/Catalog/Catalog.API/settings.json index bac26f3b5..f922656c7 100644 --- a/src/Services/Catalog/Catalog.API/settings.json +++ b/src/Services/Catalog/Catalog.API/settings.json @@ -1,5 +1,5 @@ { - "ConnectionString": "Server=tcp:127.0.0.1,5433;Initial Catalog=CatalogDB;User Id=sa;Password=Pass@word", + "ConnectionString": "Server=tcp:127.0.0.1,5433;Initial Catalog=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word", "Logging": { "IncludeScopes": false, "LogLevel": { diff --git a/src/Services/Identity/eShopOnContainers.Identity/AppSettings.cs b/src/Services/Identity/eShopOnContainers.Identity/AppSettings.cs new file mode 100644 index 000000000..bc81ecf36 --- /dev/null +++ b/src/Services/Identity/eShopOnContainers.Identity/AppSettings.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace eShopOnContainers.Identity +{ + public class AppSettings + { + public string MvcClient { get; set; } + } +} diff --git a/src/Services/Identity/eShopOnContainers.Identity/Configuration/Config.cs b/src/Services/Identity/eShopOnContainers.Identity/Configuration/Config.cs index 3d413dcc7..5a5989b56 100644 --- a/src/Services/Identity/eShopOnContainers.Identity/Configuration/Config.cs +++ b/src/Services/Identity/eShopOnContainers.Identity/Configuration/Config.cs @@ -78,7 +78,7 @@ namespace eShopOnContainers.Identity.Configuration new Secret("secret".Sha256()) }, ClientUri = $"{clientsUrl["Mvc"]}", // public uri of the client - AllowedGrantTypes = GrantTypes.HybridAndClientCredentials, + AllowedGrantTypes = GrantTypes.Hybrid, RedirectUris = new List { $"{clientsUrl["Mvc"]}/signin-oidc", diff --git a/src/Services/Identity/eShopOnContainers.Identity/Controllers/AccountController.cs b/src/Services/Identity/eShopOnContainers.Identity/Controllers/AccountController.cs index 3223feefd..58950f83d 100644 --- a/src/Services/Identity/eShopOnContainers.Identity/Controllers/AccountController.cs +++ b/src/Services/Identity/eShopOnContainers.Identity/Controllers/AccountController.cs @@ -85,15 +85,9 @@ namespace IdentityServer4.Quickstart.UI.Controllers if (ModelState.IsValid) { var user = await _loginService.FindByUsername(model.Email); - // validate username/password against in-memory store if (await _loginService.ValidateCredentials(user, model.Password)) { - // issue authentication cookie with subject ID and username - //var user = _loginService.FindByUsername(model.Username); - - AuthenticationProperties props = null; - // only set explicit expiration here if persistent. - // otherwise we reply upon expiration configured in cookie middleware. + AuthenticationProperties props = null; if (model.RememberMe) { props = new AuthenticationProperties @@ -217,15 +211,7 @@ namespace IdentityServer4.Quickstart.UI.Controllers // get context information (client name, post logout redirect URI and iframe for federated signout) var logout = await _interaction.GetLogoutContextAsync(model.LogoutId); - - var vm = new LoggedOutViewModel - { - PostLogoutRedirectUri = logout?.PostLogoutRedirectUri, - ClientName = logout?.ClientId, - SignOutIframeUrl = logout?.SignOutIFrameUrl - }; - - return View("LoggedOut", vm); + return Redirect(logout?.PostLogoutRedirectUri); } /// diff --git a/src/Services/Identity/eShopOnContainers.Identity/Controllers/HomeController.cs b/src/Services/Identity/eShopOnContainers.Identity/Controllers/HomeController.cs index 85677ba01..6814bb456 100644 --- a/src/Services/Identity/eShopOnContainers.Identity/Controllers/HomeController.cs +++ b/src/Services/Identity/eShopOnContainers.Identity/Controllers/HomeController.cs @@ -2,9 +2,11 @@ // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. +using eShopOnContainers.Identity; using IdentityServer4.Quickstart.UI.Models; using IdentityServer4.Services; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Options; using System.Threading.Tasks; namespace IdentityServer4.Quickstart.UI.Controllers @@ -12,14 +14,19 @@ namespace IdentityServer4.Quickstart.UI.Controllers public class HomeController : Controller { private readonly IIdentityServerInteractionService _interaction; + private readonly IOptions _settings; - public HomeController(IIdentityServerInteractionService interaction) + public HomeController(IIdentityServerInteractionService interaction, IOptions settings) { _interaction = interaction; + _settings = settings; } - public IActionResult Index() + public IActionResult Index(string returnUrl) { + if (returnUrl != "") + return Redirect(_settings.Value.MvcClient); + return View(); } diff --git a/src/Services/Identity/eShopOnContainers.Identity/Startup.cs b/src/Services/Identity/eShopOnContainers.Identity/Startup.cs index e8b895fef..2c9a08521 100644 --- a/src/Services/Identity/eShopOnContainers.Identity/Startup.cs +++ b/src/Services/Identity/eShopOnContainers.Identity/Startup.cs @@ -51,8 +51,8 @@ namespace eShopOnContainers.Identity services.AddIdentity() .AddEntityFrameworkStores() .AddDefaultTokenProviders(); - - + + services.Configure(Configuration); services.AddMvc(); diff --git a/src/Services/Identity/eShopOnContainers.Identity/Views/Shared/_Layout.cshtml b/src/Services/Identity/eShopOnContainers.Identity/Views/Shared/_Layout.cshtml index 1510a0e76..4e582e712 100644 --- a/src/Services/Identity/eShopOnContainers.Identity/Views/Shared/_Layout.cshtml +++ b/src/Services/Identity/eShopOnContainers.Identity/Views/Shared/_Layout.cshtml @@ -18,20 +18,6 @@ - - @*@if (User.Identity.IsAuthenticated) - { - - }*@ diff --git a/src/Services/Identity/eShopOnContainers.Identity/appsettings.json b/src/Services/Identity/eShopOnContainers.Identity/appsettings.json index 0048c419f..5a8c6d1fd 100644 --- a/src/Services/Identity/eShopOnContainers.Identity/appsettings.json +++ b/src/Services/Identity/eShopOnContainers.Identity/appsettings.json @@ -1,6 +1,6 @@ { "ConnectionStrings": { - "DefaultConnection": "Server=127.0.0.1,5433;Database=aspnet-Microsoft.eShopOnContainers;User Id=sa;Password=Pass@word" + "DefaultConnection": "Server=127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.IdentityDb;User Id=sa;Password=Pass@word" }, "MvcClient": "http://localhost:5100", "SpaClient": "http://localhost:5104", diff --git a/src/Services/Identity/eShopOnContainers.Identity/docker-compose.yml b/src/Services/Identity/eShopOnContainers.Identity/docker-compose.yml index e47763c0f..72933a273 100644 --- a/src/Services/Identity/eShopOnContainers.Identity/docker-compose.yml +++ b/src/Services/Identity/eShopOnContainers.Identity/docker-compose.yml @@ -5,7 +5,7 @@ services: image: eshop/identity environment: - SpaClient=http://localhost:5104 - - ConnectionStrings__DefaultConnection=Server=identity.data;Database=aspnet-Microsoft.eShopOnContainers;User Id=sa;Password=Pass@word + - ConnectionStrings__DefaultConnection=Server=identity.data;Database=Microsoft.eShopOnContainers.Services.IdentityDb;User Id=sa;Password=Pass@word #- MvcClient=http://104.40.62.65:5100 #Remote: VM Needs to have public access at 5105. - MvcClient=http://localhost:5100 #Local: You need a entry in windows host file to run identity in local docker. ports: @@ -13,7 +13,7 @@ services: depends_on: - identity.data - identity.data: + sql.data: image: microsoft/mssql-server-linux environment: - SA_PASSWORD=Pass@word diff --git a/src/Services/Ordering/Ordering.API/Application/Commands/NewOrderRequest.cs b/src/Services/Ordering/Ordering.API/Application/Commands/NewOrderRequest.cs new file mode 100644 index 000000000..23fab0ad6 --- /dev/null +++ b/src/Services/Ordering/Ordering.API/Application/Commands/NewOrderRequest.cs @@ -0,0 +1,48 @@ +namespace Microsoft.eShopOnContainers.Services.Ordering.Api.Application.Commands +{ + using System; + using MediatR; + using Domain; + using System.Collections; + using System.Collections.Generic; + + public class NewOrderRequest + :IAsyncRequest + { + + private readonly List _orderItems; + public string City { get; set; } + + public string Street { get; set; } + + public string State { get; set; } + + public string Country { get; set; } + + public string ZipCode { get; set; } + + public string CardNumber { get; set; } + + public string CardHolderName { get; set; } + + public DateTime CardExpiration { get; set; } + + public string CardSecurityNumber { get; set; } + + public int CardTypeId { get; set; } + + public string Buyer { get; set; } + + public IEnumerable OrderItems => _orderItems; + + public void AddOrderItem(OrderItem item) + { + _orderItems.Add(item); + } + + public NewOrderRequest() + { + _orderItems = new List(); + } + } +} diff --git a/src/Services/Ordering/Ordering.API/Application/Commands/NewOrderRequestHandler.cs b/src/Services/Ordering/Ordering.API/Application/Commands/NewOrderRequestHandler.cs new file mode 100644 index 000000000..ac5c90b86 --- /dev/null +++ b/src/Services/Ordering/Ordering.API/Application/Commands/NewOrderRequestHandler.cs @@ -0,0 +1,118 @@ +namespace Microsoft.eShopOnContainers.Services.Ordering.Api.Application.Commands +{ + using Domain.Repositories; + using MediatR; + using System.Linq; + using System; + using System.Threading.Tasks; + using Domain; + + public class NewOrderRequestHandler + : IAsyncRequestHandler + { + private readonly IBuyerRepository _buyerRepository; + private readonly IOrderRepository _orderRepository; + + public NewOrderRequestHandler(IBuyerRepository buyerRepository,IOrderRepository orderRepository) + { + if (buyerRepository == null) + { + throw new ArgumentNullException(nameof(buyerRepository)); + } + + if (orderRepository == null) + { + throw new ArgumentNullException(nameof(orderRepository)); + } + + _buyerRepository = buyerRepository; + _orderRepository = orderRepository; + } + public async Task Handle(NewOrderRequest message) + { + //find buyer/payment or add a new one buyer/payment + + var buyer = await _buyerRepository.FindAsync(message.Buyer); + + if (buyer == null) + { + buyer = CreateBuyer(message); + } + + var payment = GetExistingPaymentOrAddANewOne(buyer, message); + + await _buyerRepository.UnitOfWork + .SaveChangesAsync(); + + //create order for buyer and payment method + + var order = CreateOrder(buyer.Id, payment.Id, 0); + order.SetAddress( new Address() + { + City = message.City, + State = message.State, + Street = message.Street, + ZipCode = message.ZipCode + }); + + foreach (var item in message.OrderItems) + { + order.AddOrderItem(item); + } + + _orderRepository.Add(order); + + var result = await _orderRepository.UnitOfWork + .SaveChangesAsync(); + + return result > 0; + } + + + + Payment GetExistingPaymentOrAddANewOne(Buyer buyer, NewOrderRequest message) + { + Payment payment = PaymentAlreadyExist(buyer, message); + + if (payment == null) + { + payment = CreatePayment(message); + buyer.Payments.Add(payment); + } + + return payment; + + } + + Payment PaymentAlreadyExist(Domain.Buyer buyer, NewOrderRequest message) + { + return buyer.Payments + .SingleOrDefault(p => + { + return p.CardHolderName == message.CardHolderName + && + p.CardNumber == message.CardNumber + && + p.Expiration == message.CardExpiration + && + p.SecurityNumber == message.CardSecurityNumber; + }); + } + + Buyer CreateBuyer(NewOrderRequest message) + { + return _buyerRepository.Add( + new Buyer(message.Buyer)); + } + + Order CreateOrder(int buyerId, int paymentId, int addressId) + { + return new Order(buyerId, paymentId); + } + + Payment CreatePayment(NewOrderRequest message) + { + return new Payment(message.CardNumber, message.CardSecurityNumber, message.CardHolderName, message.CardExpiration, message.CardTypeId); + } + } +} diff --git a/src/Services/Ordering/Ordering.API/Application/Decorators/LogDecorator.cs b/src/Services/Ordering/Ordering.API/Application/Decorators/LogDecorator.cs new file mode 100644 index 000000000..6830d9db0 --- /dev/null +++ b/src/Services/Ordering/Ordering.API/Application/Decorators/LogDecorator.cs @@ -0,0 +1,34 @@ +namespace Microsoft.eShopOnContainers.Services.Ordering.Api.Application.Decorators +{ + using Extensions.Logging; + using MediatR; + using System.Threading.Tasks; + + public class LogDecorator + : IAsyncRequestHandler + where TRequest : IAsyncRequest + { + private readonly IAsyncRequestHandler _inner; + private readonly ILogger> _logger; + + + public LogDecorator( + IAsyncRequestHandler inner, + ILogger> logger) + { + _inner = inner; + _logger = logger; + } + + public async Task Handle(TRequest message) + { + _logger.LogInformation($"Executing command {_inner.GetType().FullName}"); + + var response = await _inner.Handle(message); + + _logger.LogInformation($"Succedded executed command {_inner.GetType().FullName}"); + + return response; + } + } +} diff --git a/src/Services/Ordering/Ordering.API/Application/Queries/IOrderQueries.cs b/src/Services/Ordering/Ordering.API/Application/Queries/IOrderQueries.cs new file mode 100644 index 000000000..c036e8806 --- /dev/null +++ b/src/Services/Ordering/Ordering.API/Application/Queries/IOrderQueries.cs @@ -0,0 +1,13 @@ +namespace Microsoft.eShopOnContainers.Services.Ordering.Api.Application.Queries +{ + using System.Threading.Tasks; + + public interface IOrderQueries + { + Task GetOrder(int id); + + Task GetOrders(); + + Task GetCardTypes(); + } +} diff --git a/src/Services/Ordering/Ordering.API/Application/Queries/OrderQueries.cs b/src/Services/Ordering/Ordering.API/Application/Queries/OrderQueries.cs new file mode 100644 index 000000000..899b3dccc --- /dev/null +++ b/src/Services/Ordering/Ordering.API/Application/Queries/OrderQueries.cs @@ -0,0 +1,101 @@ +namespace Microsoft.eShopOnContainers.Services.Ordering.Api.Application.Queries +{ + using Dapper; + using Microsoft.Extensions.Configuration; + using System.Data.SqlClient; + using System.Threading.Tasks; + using System; + using System.Dynamic; + using System.Collections.Generic; + + public class OrderQueries + :IOrderQueries + { + private string _connectionString = string.Empty; + + public OrderQueries(IConfiguration configuration) + { + _connectionString = configuration["ConnectionString"]; + } + + + public async Task GetOrder(int id) + { + using (var connection = new SqlConnection(_connectionString)) + { + connection.Open(); + + var result = await connection.QueryAsync( + @"select o.[Id] as ordernumber,o.OrderDate as date, os.Name as status, + oi.ProductName as productname, oi.Units as units, oi.UnitPrice as unitprice, oi.PictureUrl as pictureurl, + oa.Street as street, oa.City as city, oa.Country as country, oa.State as state, oa.ZipCode as zipcode + FROM ordering.Orders o + LEFT JOIN ordering.Orderitems oi ON o.Id = oi.orderid + LEFT JOIN ordering.orderstatus os on o.StatusId = os.Id + LEFT JOIN ordering.address oa on o.ShippingAddressId = oa.Id + WHERE o.Id=@id" + , new { id } + ); + + if (result.AsList().Count == 0) + throw new KeyNotFoundException(); + + return MapOrderItems(result); + } + } + + public async Task GetOrders() + { + using (var connection = new SqlConnection(_connectionString)) + { + connection.Open(); + + return await connection.QueryAsync(@"SELECT o.[Id] as ordernumber,o.[OrderDate] as [date],os.[Name] as [status],SUM(oi.units*oi.unitprice) as total + FROM [ordering].[Orders] o + LEFT JOIN[ordering].[orderitems] oi ON o.Id = oi.orderid + LEFT JOIN[ordering].[orderstatus] os on o.StatusId = os.Id + GROUP BY o.[Id], o.[OrderDate], os.[Name]"); + } + } + + public async Task GetCardTypes() + { + using (var connection = new SqlConnection(_connectionString)) + { + connection.Open(); + + return await connection.QueryAsync("SELECT * FROM ordering.cardtypes"); + } + } + + private dynamic MapOrderItems(dynamic result) + { + dynamic order = new ExpandoObject(); + + order.ordernumber = result[0].ordernumber; + order.date = result[0].date; + order.status = result[0].status; + order.street = result[0].street; + order.city = result[0].city; + order.zipcode = result[0].zipcode; + order.country = result[0].country; + + order.orderitems = new List(); + order.total = 0; + + foreach (dynamic item in result) + { + dynamic orderitem = new ExpandoObject(); + orderitem.productname = item.productname; + orderitem.units = item.units; + orderitem.unitprice = item.unitprice; + orderitem.pictureurl = item.pictureurl; + + order.total += item.units * item.unitprice; + order.orderitems.Add(orderitem); + } + + return order; + } + } +} diff --git a/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs b/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs index b3a4a477b..cad3bf4c1 100644 --- a/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs +++ b/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs @@ -1,7 +1,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers { - using Application.Commands; - using Application.Queries; + using Api.Application.Commands; + using Api.Application.Queries; using AspNetCore.Authorization; using MediatR; using Microsoft.AspNetCore.Mvc; @@ -11,7 +11,7 @@ using System.Threading.Tasks; [Route("api/v1/[controller]")] - [Authorize] + //[Authorize] public class OrdersController : Controller { private readonly IMediator _mediator; diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/ApplicationModule.cs b/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/ApplicationModule.cs index 2c159c4b3..327651329 100644 --- a/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/ApplicationModule.cs +++ b/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/ApplicationModule.cs @@ -2,7 +2,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.AutofacModules { - using Application.Queries; + using Api.Application.Queries; using Autofac; using Domain.Repositories; using Ordering.Infrastructure.Repositories; diff --git a/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/MediatorModule.cs b/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/MediatorModule.cs index 36427aefd..0163ccca4 100644 --- a/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/MediatorModule.cs +++ b/src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/MediatorModule.cs @@ -1,7 +1,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.AutofacModules { - using Application.Commands; - using Application.Decorators; + using Api.Application.Commands; + using Api.Application.Decorators; using Autofac; using Autofac.Core; using MediatR; diff --git a/src/Services/Ordering/Ordering.API/project.json b/src/Services/Ordering/Ordering.API/project.json index 017d911f4..0c4d597ea 100644 --- a/src/Services/Ordering/Ordering.API/project.json +++ b/src/Services/Ordering/Ordering.API/project.json @@ -19,16 +19,16 @@ "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0", "Microsoft.EntityFrameworkCore.SqlServer": "1.0.1", "Microsoft.EntityFrameworkCore": "1.0.1", - "Microsoft.EntityFrameworkCore.Design" : "1.0.0-preview2-final", + "Microsoft.EntityFrameworkCore.Design": "1.0.0-preview2-final", "Microsoft.EntityFrameworkCore.SqlServer.Design": "1.0.1", "Microsoft.AspNetCore.Diagnostics": "1.0.0", "Swashbuckle": "6.0.0-beta902", "MediatR": "2.1.0", "Ordering.Domain": "1.0.0-*", - "Ordering.Application": "1.0.0-*", "Ordering.Infrastructure": "1.0.0-*", "System.Reflection": "4.3.0", - "IdentityServer4.AccessTokenValidation": "1.0.1-rc3" + "IdentityServer4.AccessTokenValidation": "1.0.1-rc3", + "Dapper": "1.50.2" }, "tools": { "Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final", diff --git a/src/Web/WebMVC/Services/OrderingService.cs b/src/Web/WebMVC/Services/OrderingService.cs index 7deaf8620..81fe311a4 100644 --- a/src/Web/WebMVC/Services/OrderingService.cs +++ b/src/Web/WebMVC/Services/OrderingService.cs @@ -65,7 +65,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services order.CardNumber = user.CardNumber; order.CardHolderName = user.CardHolderName; - //order.CardExpiration = user.Expiration; + order.CardExpiration = new DateTime(1,int.Parse(user.Expiration.Split('/')[0]), int.Parse("20" + user.Expiration.Split('/')[1])); order.CardSecurityNumber = user.SecurityNumber; return order; diff --git a/src/Web/WebMVC/wwwroot/css/site.min.css b/src/Web/WebMVC/wwwroot/css/site.min.css index 35d022759..00d9a0a72 100644 --- a/src/Web/WebMVC/wwwroot/css/site.min.css +++ b/src/Web/WebMVC/wwwroot/css/site.min.css @@ -1 +1 @@ -@font-face{font-family:Montserrat;font-weight:400;src:url("/fonts/Montserrat-Regular.eot?") format("eot"),url("/fonts/Montserrat-Regular.woff") format("woff"),url("/fonts/Montserrat-Regular.ttf") format("truetype"),url("/fonts/Montserrat-Regular.svg#Montserrat") format("svg")}@font-face{font-family:Montserrat;font-weight:700;src:url("/fonts/Montserrat-Bold.eot?") format("eot"),url("/fonts/Montserrat-Bold.woff") format("woff"),url("/fonts/Montserrat-Bold.ttf") format("truetype"),url("/fonts/Montserrat-Bold.svg#Montserrat") format("svg")}body{padding-top:80px;font-family:Montserrat,sans-serif;min-width:480px}.mt-15{margin-top:15px}.body-content{padding-left:15px;padding-right:15px}input,select,textarea{max-width:280px}.select-filter{background-color:transparent;padding:10px;margin:10px;margin-right:20px;color:#fff;padding-top:20px;padding-bottom:3px;min-width:140px;border-color:#37c7ca;max-height:43px;-webkit-appearance:none}.select-filter option{background-color:#00a69c}select::-ms-expand{display:none}.select-filter-wrapper{z-index:0;display:inline-block;margin-left:-10px}.select-filter-wrapper::before{content:attr(data-name);opacity:.5;z-index:1;text-transform:uppercase;position:absolute;font-size:10px;margin-top:15px;margin-left:21px;color:#fff}.select-filter-arrow{position:absolute;margin-left:130px;margin-top:40px}.btn-brand-small-filter{margin-top:10px;position:absolute;margin-left:15px}.carousel-caption p{font-size:20px;line-height:1.4}.layout-cart-image{height:36px;margin-top:5px}.layout-cart-badge{position:absolute;margin-top:2px;margin-left:14px;background-color:#83d01b;padding:1px;color:#fff;border-radius:50%;width:18px;height:18px;font-size:12px;cursor:pointer}.btn-bracketed:hover:before{display:inline-block;content:"[";padding-right:.5em;color:#7fff00}.btn-bracketed:hover:after{display:inline-block;content:"]";padding-left:.5em;color:#7fff00}.btn-brand{background-color:#83d01b;color:#fff;padding:10px 20px 10px 20px;border-radius:0;border:none;width:255px;display:inline-block;text-align:center;text-transform:uppercase;height:45px;font-size:16px;font-weight:normal}.btn-brand::before{content:'['}.btn-brand::after{content:']'}.btn-brand:hover:before{padding-right:5px}.btn-brand:hover:after{padding-left:5px}.btn-brand-big{width:360px;margin-top:20px}.btn-brand-small{width:45px}.btn-brand-small::before{content:''}.btn-brand-small::after{content:''}.btn-brand-small:hover:before{content:'';padding:0}.btn-brand-small:hover:after{content:'';padding:0}.btn-brand-dark{background-color:#00a69c}.btn-brand:hover{color:#fff;background-color:#83d01b;text-decoration:none}.btn-brand-dark:hover{background-color:#00a69c}.btn-cart{float:right;margin-top:40px;margin-bottom:40px}.btn-catalog-apply{padding:0}.form-label{text-transform:uppercase;font-weight:normal!important;text-align:left;margin-bottom:10px !important;color:#404040}.form-input{border-radius:0;padding:10px;height:45px}.form-input-small{max-width:100px!important}.form-select{border-radius:0;padding:10px;height:45px;width:150px}.carousel-inner .item img[src$=".svg"]{width:100%}.navbar-inverse{background-color:#fff;border-color:#fff}.btn-login{border:1px solid #00a69c;height:36px!important;margin-right:10px;margin-top:10px;background-color:#fff;color:#00a69c;text-transform:uppercase;max-width:140px;width:140px;padding-top:8px!important}.btn-login{font-weight:normal!important}.btn-login::before{content:'['}.btn-login::after{content:']'}.btn-login:hover:before{content:'[ '}.btn-login:hover:after{content:' ]'}.navbar-inverse li a{height:30px;padding:5px 20px;color:#00a69c !important}.navbar-brand{margin-top:20px;background-image:url(../images/brand.PNG);width:201px;height:44px;margin-left:0 !important}.nav>li>a{color:#fff}.nav>li>a:hover,.nav>li>a:focus{background-color:#00a69c;font-weight:bolder}.container-fluid{padding-left:0;padding-right:0}.home-banner{width:100%;margin-right:0;margin-left:0;background-image:url(../images/main_banner.png);background-size:cover;height:258px;background-position:center}.home-banner-text{margin-top:70px}.home-catalog-container{min-height:400px;margin-bottom:20px}.home-catalog-filter-container{background-color:#00a69c;height:63px}.home-catalog-filter-container li a{padding-top:5px !important}.home-catalog-filter-brands::before{content:'BRAND';color:#fff;font-size:x-small;opacity:.5;margin:10px 0 0 15px}.home-catalog-filter-types::before{content:'TYPES';color:#fff;font-size:x-small;opacity:.5;margin:10px 0 0 15px}.home-catalog-item{margin-top:10px;margin-bottom:10px}.home-catalog-item-image{width:100%;object-fit:cover;text-align:center}.home-catalog-item-image-addCart{background-color:#83d01b;color:#fff;display:inline-block;height:43px;padding:10px 20px 10px 20px;font-weight:bold;text-align:center;margin-top:10px;margin-left:60px;margin-right:60px;font-size:16px;font-weight:normal}.home-catalog-item-image-addCart:hover{color:#fff;text-decoration:none}.home-catalog-item-image:hover:after{cursor:pointer}.home-catalog-item-title{text-align:center;text-transform:uppercase;font-weight:300;font-size:16px;margin-top:20px}.home-catalog-item-price{text-align:center;font-weight:900;font-size:28px}.home-catalog-item-price::before{content:'$'}.home-catalog-noResults{text-align:center;margin-top:100px}.container .nav .navbar-nav .col-sm-6 ::before{content:'BRAND'}.validation-summary-errors li{list-style:none}footer{background-color:#000;height:150px;vertical-align:middle}footer .brand{margin-top:25px;background-image:url(../images/brand_dark.PNG);max-width:231px;height:52px;margin-left:0 !important}footer .text{text-align:right;width:100%;height:100%;color:#83d01b;margin-top:10px}.text{color:#83d01b}.text:hover{color:#83d01b}form .col-md-4{text-align:right}.brand-header-block{background-color:#00a69c;height:63px}.brand-header-block li{list-style:none;display:inline;opacity:.5;margin-top:25px;margin-left:10px;float:right;cursor:pointer;color:#fff}.brand-header-block li a{color:#fff}.brand-header-block li a:hover{text-decoration:none}.brand-header-block .active{opacity:1}.brand-header-block .active::before{content:'[ ';color:#adff2f}.brand-header-block .active::after{content:' ]';color:#adff2f}.brand-header-back{float:left!important;margin-top:20px!important;text-transform:uppercase}.account-login-container{min-height:70vh;text-align:center;padding-top:40px}.account-register-container{min-height:70vh;text-align:center !important;align-content:center}.cart-index-container{min-height:70vh;padding-top:40px;margin-bottom:30px;min-width:992px}.register-container{min-height:70vh;padding-top:40px;margin-bottom:30px;padding-left:30px}.order-create-container{min-height:70vh;padding-top:40px;margin-bottom:30px;padding-left:30px;min-width:995px}.cart-product-column{max-width:120px;text-transform:uppercase;vertical-align:middle!important}.order-create-container .cart-product-column{max-width:130px}.cart-product-column-name{width:220px}.cart-subtotal-label{font-size:12px;color:#404040;margin-top:10px}.cart-subtotal-value{font-size:20px;color:#00a69c}.cart-total-label{font-size:14px;color:#404040;margin-top:10px}.cart-total-value{font-size:28px;color:#00a69c;text-align:left}.cart-product-image{max-width:210px}.cart-section-total{margin-bottom:5px;margin-left:175px;text-align:left}.cart-product-column input{width:70px;text-align:center}.cart-refresh-button{margin-top:0;background-image:url('../images/refresh.svg');color:#fff;font-size:8px;width:40px;height:40px;background-color:transparent;border:none;margin-top:25px;margin-left:15px}.cart-refresh-button:hover{background-color:transparent}.cart-totals{border-bottom:none!important}.input-validation-error{border:1px solid #fb0d0d}.text-danger{color:#fb0d0d;font-size:12px}.cart{border:none !important}.form-horizontal h4{margin-top:30px}.form-horizontal .form-group{margin-right:0!important}.form-control:focus{border-color:#83d01b}.form-input-center{margin:auto}.order-index-container{min-height:70vh;padding-top:40px;margin-bottom:30px}.order-index-container .table tbody tr{border-bottom:none}.order-index-container .table tbody tr td{border-top:none;padding-top:10px;padding-bottom:10px}.order-index-container .table tbody tr:nth-child(even){background-color:#f5f5f5}.order-create-section-title{margin-left:-15px;text-transform:uppercase}.order-create-section-items{margin-left:-45px;width:102%}.order-detail-button a{color:#83d01b}.order-detail-container{min-height:70vh;padding-top:40px;margin-bottom:30px}.order-detail-container .table tbody tr:first-child td{border-top:none}.order-detail-container .table tr{border-bottom:none}.order-detail-section{margin-top:50px}.order-detail-container .table{margin-left:-7px}.order-section-total{margin-bottom:5px;margin-left:40px;text-align:left}.fr{float:right!important}.down-arrow{background-image:url('../images/arrow-down.png');height:7px;width:10px;display:inline-block;margin-left:20px}.logout-icon{background-image:url('../images/logout.PNG');display:inline-block;height:19px;width:19px;margin-left:15px}.myorders-icon{background-image:url('../images/my_orders.PNG');display:inline-block;height:20px;width:20px;margin-left:15px}.login-user{position:absolute!important;top:30px;right:65px;cursor:pointer}.login-user-dropdown{position:relative;display:inline-block}.login-user-dropdown-content{display:none;position:absolute;background-color:#fff;min-width:160px;box-shadow:0 8px 16px 0 rgba(0,0,0,.2);right:0}.login-user-dropdown-content a{color:#000;padding:12px 16px;text-decoration:none;display:block;text-align:right;text-transform:uppercase}.login-user:hover .login-user-dropdown-content{display:block}.down-arrow:hover>.login-user-dropdown-content{display:block}.login-user-dropdown-content a:hover{color:#83d01b}.es-header{min-height:80px!important}.es-pager-bottom{margin-top:40px}.es-pager-top{margin-bottom:20px;margin-top:20px}.es-pager-top ul{list-style:none}.es-pager-bottom ul{list-style:none}.page-item{cursor:pointer}.next{position:absolute;right:15px;top:0}.previous{position:absolute;left:0;top:0}.is-disabled{cursor:not-allowed;opacity:.5;pointer-events:none}.table tr{border-bottom:1px solid #ddd}.table th{text-transform:uppercase}.navbar-nav{margin-top:10px;margin-bottom:7.5px;margin-right:-10px;float:right}@media screen and (max-width:1195px){.cart-product-column-name{display:none}}@media screen and (max-width:767px){.carousel-caption{display:none}footer .text{text-align:left;margin-top:-15px}.cart-product-column-brand{display:none}}@media screen and (min-width:992px){.form-input{width:360px;max-width:360px}} \ No newline at end of file +@font-face{font-family:Montserrat;font-weight:400;src:url("/fonts/Montserrat-Regular.eot?") format("eot"),url("/fonts/Montserrat-Regular.woff") format("woff"),url("/fonts/Montserrat-Regular.ttf") format("truetype"),url("/fonts/Montserrat-Regular.svg#Montserrat") format("svg")}@font-face{font-family:Montserrat;font-weight:700;src:url("/fonts/Montserrat-Bold.eot?") format("eot"),url("/fonts/Montserrat-Bold.woff") format("woff"),url("/fonts/Montserrat-Bold.ttf") format("truetype"),url("/fonts/Montserrat-Bold.svg#Montserrat") format("svg")}body{padding-top:80px;font-family:Montserrat,sans-serif;min-width:480px}.mt-15{margin-top:15px}.body-content{padding-left:15px;padding-right:15px}input,select,textarea{max-width:280px}.select-filter{background-color:transparent;padding:10px;margin:10px;margin-right:20px;color:#fff;padding-top:20px;padding-bottom:3px;min-width:140px;border-color:#37c7ca;max-height:43px;-webkit-appearance:none}.select-filter option{background-color:#00a69c}select::-ms-expand{display:none}.select-filter-wrapper{z-index:0;display:inline-block;margin-left:-10px}.select-filter-wrapper::before{content:attr(data-name);opacity:.5;z-index:1;text-transform:uppercase;position:absolute;font-size:10px;margin-top:15px;margin-left:21px;color:#fff}.select-filter-arrow{position:absolute;margin-left:130px;margin-top:40px}.btn-brand-small-filter{margin-top:10px;position:absolute;margin-left:15px}.carousel-caption p{font-size:20px;line-height:1.4}.layout-cart-image{height:36px;margin-top:5px}.layout-cart-badge{position:absolute;margin-top:2px;margin-left:14px;background-color:#83d01b;padding:1px;color:#fff;border-radius:50%;width:18px;height:18px;font-size:12px;cursor:pointer}.btn-bracketed:hover:before{display:inline-block;content:"[";padding-right:.5em;color:#7fff00}.btn-bracketed:hover:after{display:inline-block;content:"]";padding-left:.5em;color:#7fff00}.btn-brand{background-color:#83d01b;color:#fff;padding:10px 20px 10px 20px;border-radius:0;border:none;width:255px;display:inline-block;text-align:center;text-transform:uppercase;height:45px;font-size:16px;font-weight:normal}.btn-brand::before{content:'['}.btn-brand::after{content:']'}.btn-brand:hover:before{padding-right:5px}.btn-brand:hover:after{padding-left:5px}.btn-brand-big{width:360px;margin-top:20px}.btn-brand-small{width:45px}.btn-brand-small::before{content:''}.btn-brand-small::after{content:''}.btn-brand-small:hover:before{content:'';padding:0}.btn-brand-small:hover:after{content:'';padding:0}.btn-brand-dark{background-color:#00a69c}.btn-brand:hover{color:#fff;background-color:#83d01b;text-decoration:none}.btn-brand-dark:hover{background-color:#00a69c}.btn-cart{float:right;margin-top:40px;margin-bottom:40px}.btn-catalog-apply{padding:0}.form-label{text-transform:uppercase;font-weight:normal!important;text-align:left;margin-bottom:10px !important;color:#404040}.form-input{border-radius:0;padding:10px;height:45px}.form-input-small{max-width:100px!important}.form-select{border-radius:0;padding:10px;height:45px;width:150px}.carousel-inner .item img[src$=".svg"]{width:100%}.navbar-inverse{background-color:#fff;border-color:#fff}.btn-login{border:1px solid #00a69c;height:36px!important;margin-right:10px;margin-top:10px;background-color:#fff;color:#00a69c;text-transform:uppercase;max-width:140px;width:140px;padding-top:8px!important}.btn-login{font-weight:normal!important}.btn-login::before{content:'['}.btn-login::after{content:']'}.btn-login:hover:before{content:'[ '}.btn-login:hover:after{content:' ]'}.navbar-inverse li a{height:30px;padding:5px 20px;color:#00a69c !important}.navbar-brand{margin-top:20px;background-image:url(../images/brand.PNG);width:201px;height:44px;margin-left:0 !important}.nav>li>a{color:#fff}.nav>li>a:hover,.nav>li>a:focus{background-color:#00a69c;font-weight:bolder}.container-fluid{padding-left:0;padding-right:0}.home-banner{width:100%;margin-right:0;margin-left:0;background-image:url(../images/main_banner.png);background-size:cover;height:258px;background-position:center}.home-banner-text{margin-top:70px}.home-catalog-container{min-height:400px;margin-bottom:20px}.home-catalog-filter-container{background-color:#00a69c;height:63px}.home-catalog-filter-container li a{padding-top:5px !important}.home-catalog-filter-brands::before{content:'BRAND';color:#fff;font-size:x-small;opacity:.5;margin:10px 0 0 15px}.home-catalog-filter-types::before{content:'TYPES';color:#fff;font-size:x-small;opacity:.5;margin:10px 0 0 15px}.home-catalog-item{margin-top:10px;margin-bottom:10px}.home-catalog-item-image{width:100%;object-fit:cover;text-align:center}.home-catalog-item-image-addCart{background-color:#83d01b;color:#fff;display:inline-block;height:43px;padding:10px 20px 10px 20px;font-weight:bold;text-align:center;margin-top:10px;margin-left:60px;margin-right:60px;font-size:16px;font-weight:normal}.home-catalog-item-image-addCart:hover{color:#fff;text-decoration:none}.home-catalog-item-image:hover:after{cursor:pointer}.home-catalog-item-title{text-align:center;text-transform:uppercase;font-weight:300;font-size:16px;margin-top:20px}.home-catalog-item-price{text-align:center;font-weight:900;font-size:28px}.home-catalog-item-price::before{content:'$'}.home-catalog-noResults{text-align:center;margin-top:100px}.container .nav .navbar-nav .col-sm-6 ::before{content:'BRAND'}.validation-summary-errors li{list-style:none}footer{background-color:#000;height:150px;vertical-align:middle}footer .brand{margin-top:25px;background-image:url(../images/brand_dark.PNG);max-width:231px;height:52px;margin-left:0 !important}footer .text{text-align:right;width:100%;height:100%;color:#83d01b;margin-top:10px}.text{color:#83d01b}.text:hover{color:#83d01b}form .col-md-4{text-align:right}.brand-header-block{background-color:#00a69c;height:63px}.brand-header-block li{list-style:none;display:inline;opacity:.5;margin-top:25px;margin-left:10px;float:right;cursor:pointer;color:#fff}.brand-header-block li a{color:#fff}.brand-header-block li a:hover{text-decoration:none}.brand-header-block .active{opacity:1}.brand-header-block .active::before{content:'[ ';color:#adff2f}.brand-header-block .active::after{content:' ]';color:#adff2f}.brand-header-back{float:left!important;margin-top:20px!important;text-transform:uppercase}.account-login-container{min-height:70vh;text-align:center;padding-top:40px}.account-register-container{min-height:70vh;text-align:center !important;align-content:center}.cart-index-container{min-height:70vh;padding-top:40px;margin-bottom:30px;min-width:992px}.register-container{min-height:70vh;padding-top:40px;margin-bottom:30px;padding-left:30px}.order-create-container{min-height:70vh;padding-top:40px;margin-bottom:30px;padding-left:30px;min-width:995px}.cart-product-column{max-width:120px;text-transform:uppercase;vertical-align:middle!important}.order-create-container .cart-product-column{max-width:130px}.cart-product-column-name{width:220px}.cart-subtotal-label{font-size:12px;color:#404040;margin-top:10px}.cart-subtotal-value{font-size:20px;color:#00a69c}.cart-total-label{font-size:14px;color:#404040;margin-top:10px}.cart-total-value{font-size:28px;color:#00a69c;text-align:left}.cart-product-image{max-width:210px}.cart-section-total{margin-bottom:5px;margin-left:175px;text-align:left}.cart-product-column input{width:70px;text-align:center}.cart-refresh-button{margin-top:0;background-image:url('../images/refresh.svg');color:#fff;font-size:8px;width:40px;height:40px;background-color:transparent;border:none;margin-top:25px;margin-left:15px}.cart-refresh-button:hover{background-color:transparent}.cart-totals{border-bottom:none!important}.input-validation-error{border:1px solid #fb0d0d}.text-danger{color:#fb0d0d;font-size:12px}.cart{border:none !important}.form-horizontal h4{margin-top:30px}.form-horizontal .form-group{margin-right:0!important}.form-control:focus{border-color:#83d01b}.form-input-center{margin:auto}.order-index-container{min-height:70vh;padding-top:40px;margin-bottom:30px}.order-index-container .table tbody tr{border-bottom:none}.order-index-container .table tbody tr td{border-top:none;padding-top:10px;padding-bottom:10px}.order-index-container .table tbody tr:nth-child(even){background-color:#f5f5f5}.order-create-section-title{margin-left:-15px;text-transform:uppercase}.order-create-section-items{margin-left:-45px;width:102%}.order-detail-button a{color:#83d01b}.order-detail-container{min-height:70vh;padding-top:40px;margin-bottom:30px}.order-detail-container .table tbody tr:first-child td{border-top:none}.order-detail-container .table tr{border-bottom:none}.order-detail-section{margin-top:50px}.order-detail-container .table{margin-left:-7px}.order-section-total{margin-bottom:5px;margin-left:20px;text-align:left}.fr{float:right!important}.down-arrow{background-image:url('../images/arrow-down.png');height:7px;width:10px;display:inline-block;margin-left:20px}.logout-icon{background-image:url('../images/logout.PNG');display:inline-block;height:19px;width:19px;margin-left:15px}.myorders-icon{background-image:url('../images/my_orders.PNG');display:inline-block;height:20px;width:20px;margin-left:15px}.login-user{position:absolute!important;top:30px;right:65px;cursor:pointer}.login-user-dropdown{position:relative;display:inline-block}.login-user-dropdown-content{display:none;position:absolute;background-color:#fff;min-width:160px;box-shadow:0 8px 16px 0 rgba(0,0,0,.2);right:0}.login-user-dropdown-content a{color:#000;padding:12px 16px;text-decoration:none;display:block;text-align:right;text-transform:uppercase}.login-user:hover .login-user-dropdown-content{display:block}.down-arrow:hover>.login-user-dropdown-content{display:block}.login-user-dropdown-content a:hover{color:#83d01b}.es-header{min-height:80px!important}.es-pager-bottom{margin-top:40px}.es-pager-top{margin-bottom:20px;margin-top:20px}.es-pager-top ul{list-style:none}.es-pager-bottom ul{list-style:none}.page-item{cursor:pointer}.next{position:absolute;right:15px;top:0}.previous{position:absolute;left:0;top:0}.is-disabled{cursor:not-allowed;opacity:.5;pointer-events:none}.table tr{border-bottom:1px solid #ddd}.table th{text-transform:uppercase}.navbar-nav{margin-top:10px;margin-bottom:7.5px;margin-right:-10px;float:right}@media screen and (max-width:1195px){.cart-product-column-name{display:none}}@media screen and (max-width:767px){.carousel-caption{display:none}footer .text{text-align:left;margin-top:-15px}.cart-product-column-brand{display:none}}@media screen and (min-width:992px){.form-input{width:360px;max-width:360px}} \ No newline at end of file diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Program.cs b/src/Web/WebSPA/eShopOnContainers.WebSPA/Program.cs index 222c4d6ec..3b16eab2e 100644 --- a/src/Web/WebSPA/eShopOnContainers.WebSPA/Program.cs +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/Program.cs @@ -18,7 +18,7 @@ namespace eShopConContainers.WebSPA .UseConfiguration(config) .UseContentRoot(Directory.GetCurrentDirectory()) .UseIISIntegration() - //.UseUrls("http://localhost:1250/") + .UseUrls("http://localhost:5104/") .UseStartup() .Build();