Browse Source

Add Checkout view, My Orders view and Order Detail View, and Mvc flow for this Views...

pull/49/merge
Carlos Cañizares Estévez 8 years ago
parent
commit
eb7298c617
44 changed files with 450 additions and 1259 deletions
  1. +0
    -44
      src/Web/WebMVC/Controllers/AccountController.cs
  2. +3
    -3
      src/Web/WebMVC/Controllers/CartController.cs
  3. +0
    -395
      src/Web/WebMVC/Controllers/ManageController.cs
  4. +28
    -2
      src/Web/WebMVC/Controllers/OrderController.cs
  5. +1
    -1
      src/Web/WebMVC/Models/Address.cs
  6. +8
    -1
      src/Web/WebMVC/Models/Order.cs
  7. +4
    -3
      src/Web/WebMVC/Models/PaymentInfo.cs
  8. +23
    -19
      src/Web/WebMVC/Services/BasketService.cs
  9. +2
    -1
      src/Web/WebMVC/Services/IBasketService.cs
  10. +0
    -12
      src/Web/WebMVC/Services/IEmailSender.cs
  11. +4
    -4
      src/Web/WebMVC/Services/IOrderingService.cs
  12. +0
    -12
      src/Web/WebMVC/Services/ISmsSender.cs
  13. +0
    -25
      src/Web/WebMVC/Services/MessageServices.cs
  14. +43
    -6
      src/Web/WebMVC/Services/OrderingService.cs
  15. +2
    -5
      src/Web/WebMVC/Startup.cs
  16. +0
    -10
      src/Web/WebMVC/Views/Account/ConfirmEmail.cshtml
  17. +0
    -35
      src/Web/WebMVC/Views/Account/ExternalLoginConfirmation.cshtml
  18. +0
    -8
      src/Web/WebMVC/Views/Account/ExternalLoginFailure.cshtml
  19. +0
    -31
      src/Web/WebMVC/Views/Account/ForgotPassword.cshtml
  20. +0
    -8
      src/Web/WebMVC/Views/Account/ForgotPasswordConfirmation.cshtml
  21. +0
    -8
      src/Web/WebMVC/Views/Account/Lockout.cshtml
  22. +2
    -5
      src/Web/WebMVC/Views/Account/Login.cshtml
  23. +1
    -2
      src/Web/WebMVC/Views/Account/Register.cshtml
  24. +0
    -43
      src/Web/WebMVC/Views/Account/ResetPassword.cshtml
  25. +0
    -8
      src/Web/WebMVC/Views/Account/ResetPasswordConfirmation.cshtml
  26. +0
    -21
      src/Web/WebMVC/Views/Account/SendCode.cshtml
  27. +0
    -38
      src/Web/WebMVC/Views/Account/VerifyCode.cshtml
  28. +3
    -47
      src/Web/WebMVC/Views/Cart/Index.cshtml
  29. +6
    -6
      src/Web/WebMVC/Views/Catalog/Index.cshtml
  30. +0
    -50
      src/Web/WebMVC/Views/Catalog/Orders.cshtml
  31. +0
    -27
      src/Web/WebMVC/Views/Manage/AddPhoneNumber.cshtml
  32. +0
    -42
      src/Web/WebMVC/Views/Manage/ChangePassword.cshtml
  33. +0
    -100
      src/Web/WebMVC/Views/Manage/Index.cshtml
  34. +0
    -54
      src/Web/WebMVC/Views/Manage/ManageLogins.cshtml
  35. +0
    -38
      src/Web/WebMVC/Views/Manage/SetPassword.cshtml
  36. +0
    -30
      src/Web/WebMVC/Views/Manage/VerifyPhoneNumber.cshtml
  37. +33
    -65
      src/Web/WebMVC/Views/Order/Create.cshtml
  38. +84
    -0
      src/Web/WebMVC/Views/Order/Detail.cshtml
  39. +11
    -15
      src/Web/WebMVC/Views/Order/Index.cshtml
  40. +58
    -15
      src/Web/WebMVC/Views/Shared/Components/CartList/Default.cshtml
  41. +1
    -1
      src/Web/WebMVC/Views/Shared/_LoginPartial.cshtml
  42. +88
    -5
      src/Web/WebMVC/wwwroot/css/site.css
  43. +44
    -0
      src/Web/WebMVC/wwwroot/images/refresh.svg
  44. +1
    -14
      src/Web/WebMVC/wwwroot/js/site.js

+ 0
- 44
src/Web/WebMVC/Controllers/AccountController.cs View File

@ -19,21 +19,15 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly IEmailSender _emailSender;
private readonly ISmsSender _smsSender;
private readonly ILogger _logger;
public AccountController(
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
IEmailSender emailSender,
ISmsSender smsSender,
ILoggerFactory loggerFactory)
{
_userManager = userManager;
_signInManager = signInManager;
_emailSender = emailSender;
_smsSender = smsSender;
_logger = loggerFactory.CreateLogger<AccountController>();
}
@ -368,44 +362,6 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
return View(new SendCodeViewModel { Providers = factorOptions, ReturnUrl = returnUrl, RememberMe = rememberMe });
}
//
// POST: /Account/SendCode
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> SendCode(SendCodeViewModel model)
{
if (!ModelState.IsValid)
{
return View();
}
var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
if (user == null)
{
return View("Error");
}
// Generate the token and send it
var code = await _userManager.GenerateTwoFactorTokenAsync(user, model.SelectedProvider);
if (string.IsNullOrWhiteSpace(code))
{
return View("Error");
}
var message = "Your security code is: " + code;
if (model.SelectedProvider == "Email")
{
await _emailSender.SendEmailAsync(await _userManager.GetEmailAsync(user), "Security Code", message);
}
else if (model.SelectedProvider == "Phone")
{
await _smsSender.SendSmsAsync(await _userManager.GetPhoneNumberAsync(user), message);
}
return RedirectToAction(nameof(VerifyCode), new { Provider = model.SelectedProvider, ReturnUrl = model.ReturnUrl, RememberMe = model.RememberMe });
}
//
// GET: /Account/VerifyCode
[HttpGet]


+ 3
- 3
src/Web/WebMVC/Controllers/CartController.cs View File

@ -38,14 +38,14 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
{
var user = await _userManager.GetUserAsync(HttpContext.User);
var basket = _basketSvc.SetQuantities(user, quantities);
var vm = _basketSvc.UpdateBasket(basket);
if (action == "[ Checkout ]")
{
var order = _basketSvc.MapBasketToOrder(basket);
return RedirectToAction("Create", "Order");
}
var vm = _basketSvc.UpdateBasket(basket);
return View(vm);
}
@ -62,7 +62,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
UnitPrice = productDetails.Price,
ProductId = productId
};
_basketSvc.AddToCart(user, product);
_basketSvc.AddItemToBasket(user, product);
return RedirectToAction("Index", "Catalog");
}
}

+ 0
- 395
src/Web/WebMVC/Controllers/ManageController.cs View File

@ -1,395 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.eShopOnContainers.WebMVC.Models;
using Microsoft.eShopOnContainers.WebMVC.Models.ManageViewModels;
using Microsoft.eShopOnContainers.WebMVC.Services;
namespace Microsoft.eShopOnContainers.WebMVC.Controllers
{
[Authorize]
public class ManageController : Controller
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly IEmailSender _emailSender;
private readonly ISmsSender _smsSender;
private readonly ILogger _logger;
public ManageController(
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
IEmailSender emailSender,
ISmsSender smsSender,
ILoggerFactory loggerFactory)
{
_userManager = userManager;
_signInManager = signInManager;
_emailSender = emailSender;
_smsSender = smsSender;
_logger = loggerFactory.CreateLogger<ManageController>();
}
//
// GET: /Manage/Index
[HttpGet]
public async Task<IActionResult> Index(ManageMessageId? message = null)
{
ViewData["StatusMessage"] =
message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed."
: message == ManageMessageId.SetPasswordSuccess ? "Your password has been set."
: message == ManageMessageId.SetTwoFactorSuccess ? "Your two-factor authentication provider has been set."
: message == ManageMessageId.Error ? "An error has occurred."
: message == ManageMessageId.AddPhoneSuccess ? "Your phone number was added."
: message == ManageMessageId.RemovePhoneSuccess ? "Your phone number was removed."
: "";
var user = await GetCurrentUserAsync();
if (user == null)
{
return View("Error");
}
var model = new IndexViewModel
{
HasPassword = await _userManager.HasPasswordAsync(user),
PhoneNumber = await _userManager.GetPhoneNumberAsync(user),
TwoFactor = await _userManager.GetTwoFactorEnabledAsync(user),
Logins = await _userManager.GetLoginsAsync(user),
BrowserRemembered = await _signInManager.IsTwoFactorClientRememberedAsync(user),
User = user
};
return View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Index(IndexViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var user = await _userManager.GetUserAsync(HttpContext.User);
user.CardHolderName = model.User.CardHolderName;
user.CardNumber = model.User.CardNumber;
//user.CardType = model.User.CardType;
user.City = model.User.City;
user.Country = model.User.Country;
user.Expiration = model.User.Expiration;
user.State = model.User.State;
user.Street = model.User.Street;
user.ZipCode = model.User.ZipCode;
var result = await _userManager.UpdateAsync(user);
if (result.Succeeded)
{
_logger.LogInformation(99, "User changed his address and payment method information.");
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.ProfileUpdated });
}
AddErrors(result);
return View(model);
}
//
// POST: /Manage/RemoveLogin
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> RemoveLogin(RemoveLoginViewModel account)
{
ManageMessageId? message = ManageMessageId.Error;
var user = await GetCurrentUserAsync();
if (user != null)
{
var result = await _userManager.RemoveLoginAsync(user, account.LoginProvider, account.ProviderKey);
if (result.Succeeded)
{
await _signInManager.SignInAsync(user, isPersistent: false);
message = ManageMessageId.RemoveLoginSuccess;
}
}
return RedirectToAction(nameof(ManageLogins), new { Message = message });
}
//
// GET: /Manage/AddPhoneNumber
public IActionResult AddPhoneNumber()
{
return View();
}
//
// POST: /Manage/AddPhoneNumber
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> AddPhoneNumber(AddPhoneNumberViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
// Generate the token and send it
var user = await GetCurrentUserAsync();
if (user == null)
{
return View("Error");
}
var code = await _userManager.GenerateChangePhoneNumberTokenAsync(user, model.PhoneNumber);
await _smsSender.SendSmsAsync(model.PhoneNumber, "Your security code is: " + code);
return RedirectToAction(nameof(VerifyPhoneNumber), new { PhoneNumber = model.PhoneNumber });
}
//
// POST: /Manage/EnableTwoFactorAuthentication
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> EnableTwoFactorAuthentication()
{
var user = await GetCurrentUserAsync();
if (user != null)
{
await _userManager.SetTwoFactorEnabledAsync(user, true);
await _signInManager.SignInAsync(user, isPersistent: false);
_logger.LogInformation(1, "User enabled two-factor authentication.");
}
return RedirectToAction(nameof(Index), "Manage");
}
//
// POST: /Manage/DisableTwoFactorAuthentication
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DisableTwoFactorAuthentication()
{
var user = await GetCurrentUserAsync();
if (user != null)
{
await _userManager.SetTwoFactorEnabledAsync(user, false);
await _signInManager.SignInAsync(user, isPersistent: false);
_logger.LogInformation(2, "User disabled two-factor authentication.");
}
return RedirectToAction(nameof(Index), "Manage");
}
//
// GET: /Manage/VerifyPhoneNumber
[HttpGet]
public async Task<IActionResult> VerifyPhoneNumber(string phoneNumber)
{
var user = await GetCurrentUserAsync();
if (user == null)
{
return View("Error");
}
var code = await _userManager.GenerateChangePhoneNumberTokenAsync(user, phoneNumber);
// Send an SMS to verify the phone number
return phoneNumber == null ? View("Error") : View(new VerifyPhoneNumberViewModel { PhoneNumber = phoneNumber });
}
//
// POST: /Manage/VerifyPhoneNumber
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> VerifyPhoneNumber(VerifyPhoneNumberViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var user = await GetCurrentUserAsync();
if (user != null)
{
var result = await _userManager.ChangePhoneNumberAsync(user, model.PhoneNumber, model.Code);
if (result.Succeeded)
{
await _signInManager.SignInAsync(user, isPersistent: false);
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.AddPhoneSuccess });
}
}
// If we got this far, something failed, redisplay the form
ModelState.AddModelError(string.Empty, "Failed to verify phone number");
return View(model);
}
//
// POST: /Manage/RemovePhoneNumber
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> RemovePhoneNumber()
{
var user = await GetCurrentUserAsync();
if (user != null)
{
var result = await _userManager.SetPhoneNumberAsync(user, null);
if (result.Succeeded)
{
await _signInManager.SignInAsync(user, isPersistent: false);
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.RemovePhoneSuccess });
}
}
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error });
}
//
// GET: /Manage/ChangePassword
[HttpGet]
public IActionResult ChangePassword()
{
return View();
}
//
// POST: /Manage/ChangePassword
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> ChangePassword(ChangePasswordViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var user = await GetCurrentUserAsync();
if (user != null)
{
var result = await _userManager.ChangePasswordAsync(user, model.OldPassword, model.NewPassword);
if (result.Succeeded)
{
await _signInManager.SignInAsync(user, isPersistent: false);
_logger.LogInformation(3, "User changed their password successfully.");
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.ChangePasswordSuccess });
}
AddErrors(result);
return View(model);
}
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error });
}
//
// GET: /Manage/SetPassword
[HttpGet]
public IActionResult SetPassword()
{
return View();
}
//
// POST: /Manage/SetPassword
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> SetPassword(SetPasswordViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var user = await GetCurrentUserAsync();
if (user != null)
{
var result = await _userManager.AddPasswordAsync(user, model.NewPassword);
if (result.Succeeded)
{
await _signInManager.SignInAsync(user, isPersistent: false);
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.SetPasswordSuccess });
}
AddErrors(result);
return View(model);
}
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error });
}
//GET: /Manage/ManageLogins
[HttpGet]
public async Task<IActionResult> ManageLogins(ManageMessageId? message = null)
{
ViewData["StatusMessage"] =
message == ManageMessageId.RemoveLoginSuccess ? "The external login was removed."
: message == ManageMessageId.AddLoginSuccess ? "The external login was added."
: message == ManageMessageId.Error ? "An error has occurred."
: "";
var user = await GetCurrentUserAsync();
if (user == null)
{
return View("Error");
}
var userLogins = await _userManager.GetLoginsAsync(user);
var otherLogins = _signInManager.GetExternalAuthenticationSchemes().Where(auth => userLogins.All(ul => auth.AuthenticationScheme != ul.LoginProvider)).ToList();
ViewData["ShowRemoveButton"] = user.PasswordHash != null || userLogins.Count > 1;
return View(new ManageLoginsViewModel
{
CurrentLogins = userLogins,
OtherLogins = otherLogins
});
}
//
// POST: /Manage/LinkLogin
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult LinkLogin(string provider)
{
// Request a redirect to the external login provider to link a login for the current user
var redirectUrl = Url.Action("LinkLoginCallback", "Manage");
var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl, _userManager.GetUserId(User));
return Challenge(properties, provider);
}
//
// GET: /Manage/LinkLoginCallback
[HttpGet]
public async Task<ActionResult> LinkLoginCallback()
{
var user = await GetCurrentUserAsync();
if (user == null)
{
return View("Error");
}
var info = await _signInManager.GetExternalLoginInfoAsync(await _userManager.GetUserIdAsync(user));
if (info == null)
{
return RedirectToAction(nameof(ManageLogins), new { Message = ManageMessageId.Error });
}
var result = await _userManager.AddLoginAsync(user, info);
var message = result.Succeeded ? ManageMessageId.AddLoginSuccess : ManageMessageId.Error;
return RedirectToAction(nameof(ManageLogins), new { Message = message });
}
#region Helpers
private void AddErrors(IdentityResult result)
{
foreach (var error in result.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
}
public enum ManageMessageId
{
AddPhoneSuccess,
AddLoginSuccess,
ChangePasswordSuccess,
SetTwoFactorSuccess,
SetPasswordSuccess,
RemoveLoginSuccess,
RemovePhoneSuccess,
Error,
ProfileUpdated
}
private Task<ApplicationUser> GetCurrentUserAsync()
{
return _userManager.GetUserAsync(HttpContext.User);
}
#endregion
}
}

+ 28
- 2
src/Web/WebMVC/Controllers/OrderController.cs View File

@ -30,11 +30,37 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
var user = await _userManager.GetUserAsync(HttpContext.User);
var basket = _basketSvc.GetBasket(user);
var order = _basketSvc.MapBasketToOrder(basket);
vm.Order = order;
vm.Order = _orderSvc.MapUserInfoIntoOrder(user, order);
return View(vm);
}
[HttpPost]
public async Task<IActionResult> Create(CreateOrderViewModel model)
{
var user = await _userManager.GetUserAsync(HttpContext.User);
var basket = _basketSvc.GetBasket(user);
var order = _basketSvc.MapBasketToOrder(basket);
// override if user has changed some shipping address or payment info data.
_orderSvc.OverrideUserInfoIntoOrder(model.Order, order);
_orderSvc.CreateOrder(user, order);
//Empty basket for current user.
_basketSvc.CleanBasket(user);
//Redirect to historic list.
return RedirectToAction("Index");
}
public async Task<IActionResult> Detail(string orderId)
{
var user = await _userManager.GetUserAsync(HttpContext.User);
var order = _orderSvc.GetOrder(user, orderId);
return View(order);
}
public async Task<IActionResult> Index(Order item)
{
var user = await _userManager.GetUserAsync(HttpContext.User);


+ 1
- 1
src/Web/WebMVC/Models/Address.cs View File

@ -8,7 +8,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Models
public class Address
{
public Guid Id { get; set; }
public string Street { get; set; }
public string Street { get; set; }
public string City { get; set; }
public string State { get; set; }
public string StateCode { get; set; }


+ 8
- 1
src/Web/WebMVC/Models/Order.cs View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
@ -10,6 +11,8 @@ namespace Microsoft.eShopOnContainers.WebMVC.Models
public Order()
{
OrderItems = new List<OrderItem>();
ShippingAddress = new Address();
PaymentInfo = new PaymentInfo();
}
public string Id;
@ -24,10 +27,14 @@ namespace Microsoft.eShopOnContainers.WebMVC.Models
public int SequenceNumber { get; set; }
public virtual string BuyerId { get; set; }
public virtual Address ShippingAddress { get; set; }
public virtual PaymentInfo PaymentInfo { get; set; }
public virtual DateTime OrderDate { get; set; }
public OrderState State { get; set; }
public decimal Total() {
return OrderItems.Sum(x => x.Quantity * x.UnitPrice);
}
//(CCE) public virtual Address BillingAddress { get; set; }
//(CDLTLL) public virtual OrderStatus Status { get; set; }
}


+ 4
- 3
src/Web/WebMVC/Models/PaymentInfo.cs View File

@ -10,10 +10,11 @@ namespace Microsoft.eShopOnContainers.WebMVC.Models
public Guid Id { get; set; }
public string CardNumber {get;set;}
public string SecurityNumber { get; set; }
public int ExpirationMonth { get; set; }
public int ExpirationYear { get; set; }
public int ExpirationMonth { get; set; } //CCE: I would simplify with a string Expiration field so I guess we are not going to validate with real data. It's a demo..
public int ExpirationYear { get; set; } //CCE: Idem.
public string CardHolderName { get; set; }
public CardType CardType { get; set; }
public CardType CardType { get; set; } //CCE: Discuss with team if this is needed for a demo.
public string Expiration { get; set; } //CCE: Added to simplify..
}
public enum CardType:int


+ 23
- 19
src/Web/WebMVC/Services/BasketService.cs View File

@ -19,25 +19,6 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
public int ItemsInCart { get { return _itemsInCart; }}
public void AddToCart(ApplicationUser user, BasketItem product)
{
Basket activeOrder = GetBasket(user);
if (activeOrder == null)
{
activeOrder = new Basket()
{
BuyerId = user.Id,
Id = Guid.NewGuid().ToString(),
Items = new List<Models.BasketItem>()
};
}
activeOrder.Items.Add(product);
//CCE: lacks and httpcall to persist in the real back.end service.
_httpContextAccessor.HttpContext.Session.SetObject("MyActiveOrder", activeOrder);
}
public Basket GetBasket(ApplicationUser user)
{
Basket activeOrder;
@ -90,5 +71,28 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
return order;
}
public void AddItemToBasket(ApplicationUser user, BasketItem product)
{
Basket activeOrder = GetBasket(user);
if (activeOrder == null)
{
activeOrder = new Basket()
{
BuyerId = user.Id,
Id = Guid.NewGuid().ToString(),
Items = new List<Models.BasketItem>()
};
}
activeOrder.Items.Add(product);
//CCE: lacks and httpcall to persist in the real back.end service.
_httpContextAccessor.HttpContext.Session.SetObject("MyActiveOrder", activeOrder);
}
public void CleanBasket(ApplicationUser user)
{
_httpContextAccessor.HttpContext.Session.SetObject("MyActiveOrder", new Basket());
}
}
}

+ 2
- 1
src/Web/WebMVC/Services/IBasketService.cs View File

@ -10,9 +10,10 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
{
Basket GetBasket(ApplicationUser user);
int ItemsInCart { get; }
void AddToCart(ApplicationUser user, BasketItem product);
void AddItemToBasket(ApplicationUser user, BasketItem product);
Basket UpdateBasket(Basket basket);
Basket SetQuantities(ApplicationUser user, Dictionary<string, int> quantities);
Order MapBasketToOrder(Basket basket);
void CleanBasket(ApplicationUser user);
}
}

+ 0
- 12
src/Web/WebMVC/Services/IEmailSender.cs View File

@ -1,12 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.WebMVC.Services
{
public interface IEmailSender
{
Task SendEmailAsync(string email, string subject, string message);
}
}

+ 4
- 4
src/Web/WebMVC/Services/IOrderingService.cs View File

@ -9,9 +9,9 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
public interface IOrderingService
{
List<Order> GetMyOrders(ApplicationUser user);
Order GetOrder(ApplicationUser user, Guid orderId);
void CreateOrder(Order order);
Order GetOrder(ApplicationUser user, string orderId);
void CreateOrder(ApplicationUser user, Order order);
Order MapUserInfoIntoOrder(ApplicationUser user, Order order);
void OverrideUserInfoIntoOrder(Order original, Order destination);
}
}

+ 0
- 12
src/Web/WebMVC/Services/ISmsSender.cs View File

@ -1,12 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.WebMVC.Services
{
public interface ISmsSender
{
Task SendSmsAsync(string number, string message);
}
}

+ 0
- 25
src/Web/WebMVC/Services/MessageServices.cs View File

@ -1,25 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.WebMVC.Services
{
// This class is used by the application to send Email and SMS
// when you turn on two-factor authentication in ASP.NET Identity.
// For more details see this link http://go.microsoft.com/fwlink/?LinkID=532713
public class AuthMessageSender : IEmailSender, ISmsSender
{
public Task SendEmailAsync(string email, string subject, string message)
{
// Plug in your email service here to send an email.
return Task.FromResult(0);
}
public Task SendSmsAsync(string number, string message)
{
// Plug in your SMS service here to send a text message.
return Task.FromResult(0);
}
}
}

+ 43
- 6
src/Web/WebMVC/Services/OrderingService.cs View File

@ -23,38 +23,41 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
{
new Order()
{
Id = Guid.NewGuid().ToString(),
BuyerId = new Guid("ebcbcb4c-b032-4baa-834b-7fd66d37bc95").ToString(),
OrderDate = DateTime.Now,
State = OrderState.InProcess,
OrderItems = new List<OrderItem>()
{
new OrderItem() { UnitPrice = 12, PictureUrl = "https://fakeimg.pl/370x240/EEEEEE/000/?text=RoslynRedT-Shirt", Quantity = 1, ProductName="Roslyn Red T-Shirt" }
new OrderItem() { UnitPrice = 12.40m, PictureUrl = "https://fakeimg.pl/370x240/EEEEEE/000/?text=RoslynRedT-Shirt", Quantity = 1, ProductName="Roslyn Red T-Shirt" }
}
},
new Order()
{
Id = Guid.NewGuid().ToString(),
BuyerId = new Guid("ebcbcb4c-b032-4baa-834b-7fd66d37bc95").ToString(),
OrderDate = DateTime.Now,
State = OrderState.InProcess,
OrderItems = new List<OrderItem>()
{
new OrderItem() { UnitPrice = 12, PictureUrl = "https://fakeimg.pl/370x240/EEEEEE/000/?text=RoslynRedT-Shirt", Quantity = 1, ProductName="Roslyn Red T-Shirt" }
new OrderItem() { UnitPrice = 12.00m, PictureUrl = "https://fakeimg.pl/370x240/EEEEEE/000/?text=RoslynRedT-Shirt", Quantity = 1, ProductName="Roslyn Red T-Shirt" }
}
},
new Order()
{
Id = Guid.NewGuid().ToString(),
BuyerId = new Guid("ebcbcb4c-b032-4baa-834b-7fd66d37bc95").ToString(),
OrderDate = DateTime.Now,
State = OrderState.Delivered,
OrderItems = new List<OrderItem>()
{
new OrderItem() { UnitPrice = 12, PictureUrl = "https://fakeimg.pl/370x240/EEEEEE/000/?text=RoslynRedT-Shirt", Quantity = 1, ProductName="Roslyn Red T-Shirt" }
new OrderItem() { UnitPrice = 12.05m, PictureUrl = "https://fakeimg.pl/370x240/EEEEEE/000/?text=RoslynRedT-Shirt", Quantity = 1, ProductName="Roslyn Red T-Shirt" }
}
}
};
}
public Order GetOrder(ApplicationUser user, Guid Id)
public Order GetOrder(ApplicationUser user, string Id)
{
return _orders.Where(x => x.BuyerId.Equals(user.Id) && x.Id.Equals(Id)).FirstOrDefault();
}
@ -64,9 +67,43 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
return _orders.Where(x => x.BuyerId.Equals(user.Id)).ToList();
}
public void CreateOrder(Order order)
public Order MapUserInfoIntoOrder(ApplicationUser user, Order order)
{
throw new NotImplementedException();
order.ShippingAddress.City = user.City;
order.ShippingAddress.Street = user.Street;
order.ShippingAddress.State = user.State;
order.ShippingAddress.Country = user.Country;
order.PaymentInfo.CardNumber = user.CardNumber;
order.PaymentInfo.CardHolderName = user.CardHolderName;
order.PaymentInfo.Expiration = user.Expiration;
order.PaymentInfo.SecurityNumber = user.SecurityNumber;
return order;
}
public void CreateOrder(ApplicationUser user, Order order)
{
order.OrderDate = DateTime.Now;
order.Id = Guid.NewGuid().ToString();
order.BuyerId = user.Id;
order.SequenceNumber = new Random(100).Next();
order.State = OrderState.InProcess;
_orders.Add(order);
}
public void OverrideUserInfoIntoOrder(Order original, Order destination)
{
destination.ShippingAddress.City = original.ShippingAddress.City;
destination.ShippingAddress.Street = original.ShippingAddress.Street;
destination.ShippingAddress.State = original.ShippingAddress.State;
destination.ShippingAddress.Country = original.ShippingAddress.Country;
destination.PaymentInfo.CardNumber = original.PaymentInfo.CardNumber;
destination.PaymentInfo.CardHolderName = original.PaymentInfo.CardHolderName;
destination.PaymentInfo.Expiration = original.PaymentInfo.Expiration;
destination.PaymentInfo.SecurityNumber = original.PaymentInfo.SecurityNumber;
}
}
}

+ 2
- 5
src/Web/WebMVC/Startup.cs View File

@ -22,8 +22,7 @@ namespace Microsoft.eShopOnContainers.WebMVC
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
if (env.IsDevelopment())
{
@ -55,10 +54,8 @@ namespace Microsoft.eShopOnContainers.WebMVC
services.AddSession();
// Add application services.
services.AddTransient<IEmailSender, AuthMessageSender>();
services.AddTransient<ISmsSender, AuthMessageSender>();
services.AddSingleton<ICatalogService, CatalogService>(); //CCE: Once services are integrated, a singleton is not needed we can left transient.
services.AddTransient<IOrderingService, OrderingService>();
services.AddSingleton<IOrderingService, OrderingService>();
services.AddTransient<IBasketService, BasketService>();
services.Configure<AppSettings>(Configuration);


+ 0
- 10
src/Web/WebMVC/Views/Account/ConfirmEmail.cshtml View File

@ -1,10 +0,0 @@
@{
ViewData["Title"] = "Confirm Email";
}
<h2>@ViewData["Title"].</h2>
<div>
<p>
Thank you for confirming your email. Please <a asp-controller="Account" asp-action="Login">Click here to Log in</a>.
</p>
</div>

+ 0
- 35
src/Web/WebMVC/Views/Account/ExternalLoginConfirmation.cshtml View File

@ -1,35 +0,0 @@
@model ExternalLoginConfirmationViewModel
@{
ViewData["Title"] = "Register";
}
<h2>@ViewData["Title"].</h2>
<h3>Associate your @ViewData["LoginProvider"] account.</h3>
<form asp-controller="Account" asp-action="ExternalLoginConfirmation" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" class="form-horizontal">
<h4>Association Form</h4>
<hr />
<div asp-validation-summary="All" class="text-danger"></div>
<p class="text-info">
You've successfully authenticated with <strong>@ViewData["LoginProvider"]</strong>.
Please enter an email address for this site below and click the Register button to finish
logging in.
</p>
<div class="form-group">
<label asp-for="Email" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Email" class="form-control" />
<span asp-validation-for="Email" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="submit" class="btn btn-default">Register</button>
</div>
</div>
</form>
@section Scripts {
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
}

+ 0
- 8
src/Web/WebMVC/Views/Account/ExternalLoginFailure.cshtml View File

@ -1,8 +0,0 @@
@{
ViewData["Title"] = "Login Failure";
}
<header>
<h2>@ViewData["Title"].</h2>
<p class="text-danger">Unsuccessful login with service.</p>
</header>

+ 0
- 31
src/Web/WebMVC/Views/Account/ForgotPassword.cshtml View File

@ -1,31 +0,0 @@
@model ForgotPasswordViewModel
@{
ViewData["Title"] = "Forgot your password?";
}
<h2>@ViewData["Title"]</h2>
<p>
For more information on how to enable reset password please see this <a href="http://go.microsoft.com/fwlink/?LinkID=532713">article</a>.
</p>
@*<form asp-controller="Account" asp-action="ForgotPassword" method="post" class="form-horizontal">
<h4>Enter your email.</h4>
<hr />
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<label asp-for="Email" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Email" class="form-control" />
<span asp-validation-for="Email" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="submit" class="btn btn-default">Submit</button>
</div>
</div>
</form>*@
@section Scripts {
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
}

+ 0
- 8
src/Web/WebMVC/Views/Account/ForgotPasswordConfirmation.cshtml View File

@ -1,8 +0,0 @@
@{
ViewData["Title"] = "Forgot Password Confirmation";
}
<h2>@ViewData["Title"].</h2>
<p>
Please check your email to reset your password.
</p>

+ 0
- 8
src/Web/WebMVC/Views/Account/Lockout.cshtml View File

@ -1,8 +0,0 @@
@{
ViewData["Title"] = "Locked out";
}
<header>
<h1 class="text-danger">Locked out.</h1>
<p class="text-danger">This account has been locked out, please try again later.</p>
</header>

+ 2
- 5
src/Web/WebMVC/Views/Account/Login.cshtml View File

@ -30,23 +30,20 @@
<input asp-for="Password" class="form-control form-input form-input-center" />
<span asp-validation-for="Password" class="text-danger"></span>
</div>
@*<div class="form-group">
<div class="form-group">
<div class="checkbox">
<label asp-for="RememberMe">
<input asp-for="RememberMe" />
@Html.DisplayNameFor(m => m.RememberMe)
</label>
</div>
</div>*@
</div>
<div class="form-group">
<button type="submit" class="btn btn-default btn-brand btn-brand-big">&nbsp;LOG IN&nbsp;</button>
</div>
<p>
<a asp-action="Register" asp-route-returnurl="@ViewData["ReturnUrl"]" class="text">Register as a new user?</a>
</p>
<p>
@*<a asp-action="ForgotPassword" class="text">Forgot your password?</a>*@
</p>
</form>
</section>
</div>


+ 1
- 2
src/Web/WebMVC/Views/Account/Register.cshtml View File

@ -9,10 +9,9 @@
</ul>
</div>
<div class="container cart-index-container">
@*<h2>@ViewData["Title"].</h2>*@
<h4 class="order-create-section-title">CREATE NEW ACCOUNT</h4>
<form asp-controller="Account" asp-action="Register" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" class="form-horizontal">
@*<div asp-validation-summary="All" class="text-danger"></div>*@
<div asp-validation-summary="All" class="text-danger"></div>
<div class="row">
<div class="form-group col-sm-6">
<label asp-for="User.Name" class="control-label form-label">NAME</label>


+ 0
- 43
src/Web/WebMVC/Views/Account/ResetPassword.cshtml View File

@ -1,43 +0,0 @@
@model ResetPasswordViewModel
@{
ViewData["Title"] = "Reset password";
}
<h2>@ViewData["Title"].</h2>
<form asp-controller="Account" asp-action="ResetPassword" method="post" class="form-horizontal">
<h4>Reset your password.</h4>
<hr />
<div asp-validation-summary="All" class="text-danger"></div>
<input asp-for="Code" type="hidden" />
<div class="form-group">
<label asp-for="Email" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Email" class="form-control" />
<span asp-validation-for="Email" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label asp-for="Password" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Password" class="form-control" />
<span asp-validation-for="Password" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label asp-for="ConfirmPassword" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="ConfirmPassword" class="form-control" />
<span asp-validation-for="ConfirmPassword" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="submit" class="btn btn-default">Reset</button>
</div>
</div>
</form>
@section Scripts {
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
}

+ 0
- 8
src/Web/WebMVC/Views/Account/ResetPasswordConfirmation.cshtml View File

@ -1,8 +0,0 @@
@{
ViewData["Title"] = "Reset password confirmation";
}
<h1>@ViewData["Title"].</h1>
<p>
Your password has been reset. Please <a asp-controller="Account" asp-action="Login">Click here to log in</a>.
</p>

+ 0
- 21
src/Web/WebMVC/Views/Account/SendCode.cshtml View File

@ -1,21 +0,0 @@
@model SendCodeViewModel
@{
ViewData["Title"] = "Send Verification Code";
}
<h2>@ViewData["Title"].</h2>
<form asp-controller="Account" asp-action="SendCode" asp-route-returnurl="@Model.ReturnUrl" method="post" class="form-horizontal">
<input asp-for="RememberMe" type="hidden" />
<div class="row">
<div class="col-md-8">
Select Two-Factor Authentication Provider:
<select asp-for="SelectedProvider" asp-items="Model.Providers"></select>
<button type="submit" class="btn btn-default">Submit</button>
</div>
</div>
</form>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
}

+ 0
- 38
src/Web/WebMVC/Views/Account/VerifyCode.cshtml View File

@ -1,38 +0,0 @@
@model VerifyCodeViewModel
@{
ViewData["Title"] = "Verify";
}
<h2>@ViewData["Title"].</h2>
<form asp-controller="Account" asp-action="VerifyCode" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" class="form-horizontal">
<div asp-validation-summary="All" class="text-danger"></div>
<input asp-for="Provider" type="hidden" />
<input asp-for="RememberMe" type="hidden" />
<h4>@ViewData["Status"]</h4>
<hr />
<div class="form-group">
<label asp-for="Code" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Code" class="form-control" />
<span asp-validation-for="Code" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<div class="checkbox">
<input asp-for="RememberBrowser" />
<label asp-for="RememberBrowser"></label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="submit" class="btn btn-default">Submit</button>
</div>
</div>
</form>
@section Scripts {
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
}

+ 3
- 47
src/Web/WebMVC/Views/Cart/Index.cshtml View File

@ -14,55 +14,11 @@
<form method="post" id="cartForm">
<div class="container cart-index-container">
<div class="row">
<br /><br /><br /><br />
<div class="col-md-12">
<section>
<table class="table">
<thead>
<tr>
<th class="cart-product-column">
PRODUCT
</th>
<th>
</th>
<th>
BRAND
</th>
<th>
PRICE
</th>
<th>
QUANTITY
</th>
<th>
COST
</th>
</tr>
</thead>
<tbody>
@await Component.InvokeAsync("CartList", new { user = await UserManager.GetUserAsync(User) })
</tbody>
</table>
</section>
</div>
@await Component.InvokeAsync("CartList", new { user = await UserManager.GetUserAsync(User) })
<div class="col-md-offset-8 col-md-4">
<input type="submit"
class="btn btn-default btn-brand btn-cart cart-checkout-btn cart-refresh-button"
value="[ Refresh ]"
name="action" />
<div class="cart-section-total">
<div class="cart-subtotal-label"><span>SUBTOTAL</span></div>
<div class="cart-subtotal-value"><span>$ 29.00</span></div>
<div class="cart-subtotal-label"><span>TAX</span></div>
<div class="cart-subtotal-value"><span>$ 4.20</span></div>
<div class="cart-total-label"><span>TOTAL</span></div>
<div class="cart-total-value"><span>$ @Model.Total()</span></div>
</div>
<input type="submit"
class="btn btn-default btn-brand btn-cart cart-checkout-btn cart-refresh-button"
value="[ Checkout ]" name="action" />
class="btn btn-default btn-brand btn-cart"
value="[ Checkout ]" name="action" />
</div>
</div>
</div>

+ 6
- 6
src/Web/WebMVC/Views/Catalog/Index.cshtml View File

@ -32,7 +32,7 @@
<nav>
<ul>
<li class="page-item">
<a class="text previous @Model.PaginationInfo.Previous" id="Previous"
<a class="text previous @Model.PaginationInfo.Previous" id="Previous"
href="@Url.Action("Index","Catalog", new { page = Model.PaginationInfo.ActualPage -1 })"
aria-label="Previous">
<span>Previous</span>
@ -60,9 +60,9 @@
<div class="row">
@foreach (var catalogItem in Model.CatalogItems)
{
<form asp-controller="Cart" asp-action="AddToCart" asp-route-productId="@catalogItem.Id">
<div class="col-sm-4 home-catalog-item">
<div class="home-catalog-item-image" >
<div class="col-sm-4 home-catalog-item">
<form asp-controller="Cart" asp-action="AddToCart" asp-route-productId="@catalogItem.Id">
<div class="home-catalog-item-image">
<img src="@catalogItem.PictureUrl" />
<input type="submit" value="[ ADD TO CART ]" class="btn-brand home-catalog-item-image-addCart" />
</div>
@ -72,8 +72,8 @@
<div class="home-catalog-item-price">
<span>@catalogItem.Price.ToString("N2")</span>
</div>
</div>
</form>
</form>
</div>
}
</div>
<div class="container es-pager-bottom">


+ 0
- 50
src/Web/WebMVC/Views/Catalog/Orders.cshtml View File

@ -1,50 +0,0 @@
@{
ViewData["Title"] = "Orders";
@model IEnumerable<Order>
}
<h2>@ViewData["Title"].</h2>
<h3>@ViewData["Message"]</h3>
@foreach (var order in Model)
{
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">
<strong>Order Number:</strong> @order.OrderNumber
</h3>
</div>
<div class="panel-body">
<strong>BuyerId: </strong> @order.BuyerId <br />
<strong>OrderDate: </strong> @order.OrderDate <br />
<strong>SequenceNumber: </strong> @order.SequenceNumber <br />
</div>
<div class="panel-body">
<address>
<strong>Street: </strong> @order.ShippingAddress.Street <br />
<strong>City: </strong> @order.ShippingAddress.City <br />
<strong>State: </strong> @order.ShippingAddress.State <br />
<strong>StateCode: </strong> @order.ShippingAddress.StateCode <br />
<strong>Country: </strong> @order.ShippingAddress.Country <br />
<strong>CountryCode: </strong> @order.ShippingAddress.CountryCode <br />
<strong>ZipCode: </strong> @order.ShippingAddress.ZipCode <br />
<strong>Latitude: </strong> @order.ShippingAddress.Latitude <br />
<strong>Longitude: </strong> @order.ShippingAddress.Longitude <br />
</address>
</div>
<div class="panel-body">
@foreach (var orderItem in order.OrderItems)
{
<address>
<strong>ProductId: </strong> @orderItem.ProductId <br />
<strong>ProductName: </strong> @orderItem.ProductName <br />
<strong>Price: </strong> @orderItem.UnitPrice <br />
<strong>Quantity: </strong> @orderItem.Quantity <br />
<strong>Discount: </strong> @orderItem.Discount <br />
</address>
}
</div>
</div>
}

+ 0
- 27
src/Web/WebMVC/Views/Manage/AddPhoneNumber.cshtml View File

@ -1,27 +0,0 @@
@model AddPhoneNumberViewModel
@{
ViewData["Title"] = "Add Phone Number";
}
<h2>@ViewData["Title"].</h2>
<form asp-controller="Manage" asp-action="AddPhoneNumber" method="post" class="form-horizontal">
<h4>Add a phone number.</h4>
<hr />
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<label asp-for="PhoneNumber" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="PhoneNumber" class="form-control" />
<span asp-validation-for="PhoneNumber" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="submit" class="btn btn-default">Send verification code</button>
</div>
</div>
</form>
@section Scripts {
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
}

+ 0
- 42
src/Web/WebMVC/Views/Manage/ChangePassword.cshtml View File

@ -1,42 +0,0 @@
@model ChangePasswordViewModel
@{
ViewData["Title"] = "Change Password";
}
<form asp-controller="Manage" asp-action="ChangePassword" method="post" class="form-horizontal">
<h4>Change Password Form</h4>
<hr />
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<label asp-for="OldPassword" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="OldPassword" class="form-control" />
<span asp-validation-for="OldPassword" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label asp-for="NewPassword" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="NewPassword" class="form-control" />
<span asp-validation-for="NewPassword" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label asp-for="ConfirmPassword" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="ConfirmPassword" class="form-control" />
<span asp-validation-for="ConfirmPassword" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="submit" class="btn btn-default">Change password</button>
</div>
</div>
</form>
@section Scripts {
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
}

+ 0
- 100
src/Web/WebMVC/Views/Manage/Index.cshtml View File

@ -1,100 +0,0 @@
@model IndexViewModel
@{
ViewData["Title"] = "Manage your account";
}
@*<h2>@ViewData["Title"].</h2>*@
<p class="text-success">@ViewData["StatusMessage"]</p>
<div class="brand-header-block">
<ul class="container">
<li class="brand-header-back"><a asp-area="" asp-controller="Home" asp-action="Index">Back to list</a></li>
</ul>
</div>
<div class="container cart-index-container">
<form asp-controller="Manage" asp-action="Index" method="post" class="form-horizontal">
<div class="form-group">
<div class="col-md-offset-8 col-md-4">
<button type="submit" class="btn btn-default btn-brand">[ Save ]</button>
</div>
</div>
<h4 class="order-create-section-title">SHIPPING ADDRESS</h4>
<div class="form-horizontal row">
<div class="form-group col-sm-6">
<label asp-for="User.Street" class="control-label form-label">ADDRESS</label>
<input asp-for="User.Street" class="form-control form-input" />
<span asp-validation-for="User.Street" class="text-danger" />
</div>
<div class="form-group col-sm-6">
<label asp-for="User.City" class="control-label form-label"></label>
<input asp-for="User.City" class="form-control form-input" />
<span asp-validation-for="User.City" class="text-danger" />
</div>
<div class="form-group col-sm-6">
<label asp-for="User.State" class="control-label form-label"></label>
<input asp-for="User.State" class="form-control form-input" />
<span asp-validation-for="User.State" class="text-danger" />
</div>
<div class="form-group col-sm-6">
<label asp-for="User.Country" class="control-label form-label"></label>
<input asp-for="User.Country" class="form-control form-input" />
<span asp-validation-for="User.Country" class="text-danger" />
</div>
<div class="form-group col-sm-6">
<label asp-for="User.ZipCode" class="control-label form-label"></label>
<input asp-for="User.ZipCode" class="form-control form-input form-input-small" />
<span asp-validation-for="User.ZipCode" class="text-danger" />
</div>
</div>
<br /><br />
<div class="order-create-section-payment">
<h4 class="order-create-section-title">PAYMENT METHOD</h4>
<div class="form-horizontal row">
<div class="form-group col-sm-6">
<label asp-for="User.CardNumber" class="control-label form-label">Card Number</label>
<input asp-for="User.CardNumber" class="form-control form-input" />
<span asp-validation-for="User.CardNumber" class="text-danger" />
</div>
<div class="form-group col-sm-6">
<label asp-for="User.CardHolderName" class="control-label form-label">Cardholder Name</label>
<input asp-for="User.CardHolderName" class="form-control form-input" />
<span asp-validation-for="User.CardHolderName" class="text-danger" />
</div>
<div class="form-group col-sm-3">
<label asp-for="User.Expiration" class="control-label form-label">Expiration Date</label>
<input asp-for="User.Expiration" placeholder="MM/YY" class="form-control form-input form-input-small" />
<span asp-validation-for="User.Expiration" class="text-danger" />
</div>
<div class="form-group col-sm-3">
<label asp-for="User.SecurityNumber" class="control-label form-label">Security Code</label>
<input asp-for="User.SecurityNumber" class="form-control form-input form-input-small" />
<span asp-validation-for="User.SecurityNumber" class="text-danger" />
</div>
</div>
</div>
<br /><br />
<h4 class="order-create-section-title">Change your account settings</h4>
<div class="form-horizontal row">
<div class="form-group col-sm-6">
<label asp-for="User.Street" class="control-label form-label">PASSWORD</label>
<br />
@if (Model.HasPassword)
{
<a asp-controller="Manage" asp-action="ChangePassword" class="text">Change</a>
}
else
{
<a asp-controller="Manage" asp-action="SetPassword" class="text">Create</a>
}
</div>
</div>
<br /><br />
<div class="form-group">
<div class="col-md-offset-8 col-md-4">
<button type="submit" class="btn btn-default btn-brand">[ Save ]</button>
</div>
</div>
<br /><br />
</form>
</div>

+ 0
- 54
src/Web/WebMVC/Views/Manage/ManageLogins.cshtml View File

@ -1,54 +0,0 @@
@model ManageLoginsViewModel
@using Microsoft.AspNetCore.Http.Authentication
@{
ViewData["Title"] = "Manage your external logins";
}
<h2>@ViewData["Title"].</h2>
<p class="text-success">@ViewData["StatusMessage"]</p>
@if (Model.CurrentLogins.Count > 0)
{
<h4>Registered Logins</h4>
<table class="table">
<tbody>
@for (var index = 0; index < Model.CurrentLogins.Count; index++)
{
<tr>
<td>@Model.CurrentLogins[index].LoginProvider</td>
<td>
@if ((bool)ViewData["ShowRemoveButton"])
{
<form asp-controller="Manage" asp-action="RemoveLogin" method="post" class="form-horizontal">
<div>
<input asp-for="@Model.CurrentLogins[index].LoginProvider" name="LoginProvider" type="hidden" />
<input asp-for="@Model.CurrentLogins[index].ProviderKey" name="ProviderKey" type="hidden" />
<input type="submit" class="btn btn-default" value="Remove" title="Remove this @Model.CurrentLogins[index].LoginProvider login from your account" />
</div>
</form>
}
else
{
@: &nbsp;
}
</td>
</tr>
}
</tbody>
</table>
}
@if (Model.OtherLogins.Count > 0)
{
<h4>Add another service to log in.</h4>
<hr />
<form asp-controller="Manage" asp-action="LinkLogin" method="post" class="form-horizontal">
<div id="socialLoginList">
<p>
@foreach (var provider in Model.OtherLogins)
{
<button type="submit" class="btn btn-default" name="provider" value="@provider.AuthenticationScheme" title="Log in using your @provider.DisplayName account">@provider.AuthenticationScheme</button>
}
</p>
</div>
</form>
}

+ 0
- 38
src/Web/WebMVC/Views/Manage/SetPassword.cshtml View File

@ -1,38 +0,0 @@
@model SetPasswordViewModel
@{
ViewData["Title"] = "Set Password";
}
<p class="text-info">
You do not have a local username/password for this site. Add a local
account so you can log in without an external login.
</p>
<form asp-controller="Manage" asp-action="SetPassword" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" class="form-horizontal">
<h4>Set your password</h4>
<hr />
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<label asp-for="NewPassword" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="NewPassword" class="form-control" />
<span asp-validation-for="NewPassword" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label asp-for="ConfirmPassword" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="ConfirmPassword" class="form-control" />
<span asp-validation-for="ConfirmPassword" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="submit" class="btn btn-default">Set password</button>
</div>
</div>
</form>
@section Scripts {
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
}

+ 0
- 30
src/Web/WebMVC/Views/Manage/VerifyPhoneNumber.cshtml View File

@ -1,30 +0,0 @@
@model VerifyPhoneNumberViewModel
@{
ViewData["Title"] = "Verify Phone Number";
}
<h2>@ViewData["Title"].</h2>
<form asp-controller="Manage" asp-action="VerifyPhoneNumber" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" class="form-horizontal">
<input asp-for="PhoneNumber" type="hidden" />
<h4>Add a phone number.</h4>
<h5>@ViewData["Status"]</h5>
<hr />
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<label asp-for="Code" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Code" class="form-control" />
<span asp-validation-for="Code" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="submit" class="btn btn-default">Submit</button>
</div>
</div>
</form>
@section Scripts {
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
}

+ 33
- 65
src/Web/WebMVC/Views/Order/Create.cshtml View File

@ -1,36 +1,37 @@
@model Microsoft.eShopOnContainers.WebMVC.Models.OrderViewModels.CreateOrderViewModel
@inject UserManager<ApplicationUser> UserManager
@{
ViewData["Title"] = "View";
ViewData["Title"] = "New Order";
}
<div class="brand-header-block">
<ul class="container">
<li class="brand-header-back"><a asp-area="" asp-controller="Order" asp-action="Cart">Back to list</a></li>
<li class="brand-header-back"><a asp-area="" asp-controller="Cart" asp-action="Index">Back to cart</a></li>
</ul>
</div>
<div class="container cart-index-container">
<form asp-action="View">
<div class="container order-create-container">
<form method="post" asp-controller="Order" asp-action="Create">
<h4 class="order-create-section-title">SHIPPING ADDRESS</h4>
<div class="form-horizontal row">
<div class="form-group col-sm-6">
<label asp-for="Order.OrderNumber" class="control-label form-label">order number</label>
<input asp-for="Order.OrderNumber" class="form-control form-input" />
<span asp-validation-for="Order.OrderNumber" class="text-danger" />
<label asp-for="Order.ShippingAddress.Street" class="control-label form-label">Address</label>
<input asp-for="Order.ShippingAddress.Street" class="form-control form-input" />
<span asp-validation-for="Order.ShippingAddress.Street" class="text-danger" />
</div>
<div class="form-group col-sm-6">
<label asp-for="Order.SequenceNumber" class="control-label form-label"></label>
<input asp-for="Order.SequenceNumber" class="form-control form-input" />
<span asp-validation-for="Order.SequenceNumber" class="text-danger" />
<label asp-for="Order.ShippingAddress.City" class="control-label form-label">City</label>
<input asp-for="Order.ShippingAddress.City" class="form-control form-input" />
<span asp-validation-for="Order.ShippingAddress.City" class="text-danger" />
</div>
<div class="form-group col-sm-6">
<label asp-for="Order.BuyerId" class="control-label form-label"></label>
<input asp-for="Order.BuyerId" class="form-control form-input" />
<span asp-validation-for="Order.BuyerId" class="text-danger" />
<label asp-for="Order.ShippingAddress.State" class="control-label form-label">State</label>
<input asp-for="Order.ShippingAddress.State" class="form-control form-input" />
<span asp-validation-for="Order.ShippingAddress.State" class="text-danger" />
</div>
<div class="form-group col-sm-6">
<label asp-for="Order.OrderDate" class="control-label form-label"></label>
<input asp-for="Order.OrderDate" class="form-control form-input" />
<span asp-validation-for="Order.OrderDate" class="text-danger" />
<label asp-for="Order.ShippingAddress.Country" class="control-label form-label">Country</label>
<input asp-for="Order.ShippingAddress.Country" class="form-control form-input" />
<span asp-validation-for="Order.ShippingAddress.Country" class="text-danger" />
</div>
</div>
<br /><br />
@ -38,73 +39,40 @@
<h4 class="order-create-section-title">PAYMENT METHOD</h4>
<div class="form-horizontal row">
<div class="form-group col-sm-6">
<label asp-for="Order.OrderNumber" class="control-label form-label">Card Number</label>
<input asp-for="Order.OrderNumber" class="form-control form-input" />
<span asp-validation-for="Order.OrderNumber" class="text-danger" />
<label asp-for="Order.PaymentInfo.CardNumber" class="control-label form-label">Card Number</label>
<input asp-for="Order.PaymentInfo.CardNumber" class="form-control form-input" />
<span asp-validation-for="Order.PaymentInfo.CardNumber" class="text-danger" />
</div>
<div class="form-group col-sm-6">
<label asp-for="Order.OrderNumber" class="control-label form-label">Cardholder Name</label>
<input asp-for="Order.OrderNumber" class="form-control form-input" />
<span asp-validation-for="Order.OrderNumber" class="text-danger" />
<label asp-for="Order.PaymentInfo.CardHolderName" class="control-label form-label">Cardholder Name</label>
<input asp-for="Order.PaymentInfo.CardHolderName" class="form-control form-input" />
<span asp-validation-for="Order.PaymentInfo.CardHolderName" class="text-danger" />
</div>
</div>
<div class="form-horizontal row">
<div class="form-group col-sm-6">
<label asp-for="Order.OrderNumber" class="control-label form-label">Expiration Date</label>
<select asp-for="Order.OrderNumber" class="form-control form-select" />
<span asp-validation-for="Order.OrderNumber" class="text-danger" />
<br />
<label asp-for="Order.OrderDate" class="control-label form-label">hhh</label>
<select asp-for="Order.OrderDate" class="form-control form-select" />
<span asp-validation-for="Order.OrderDate" class="text-danger" />
<div class="form-group col-sm-3">
<label asp-for="Order.PaymentInfo.Expiration" class="control-label form-label">Expiration Date</label>
<input asp-for="Order.PaymentInfo.Expiration" placeholder="MM/YY" class="form-control form-select" />
<span asp-validation-for="Order.PaymentInfo.Expiration" class="text-danger" />
</div>
<div class="form-group col-sm-6">
<label asp-for="Order.OrderNumber" class="control-label form-label">Security Code</label>
<input asp-for="Order.OrderNumber" class="form-control form-input form-input-small" />
<span asp-validation-for="Order.OrderNumber" class="text-danger" />
<div class="form-group col-sm-3">
<label asp-for="Order.PaymentInfo.SecurityNumber" class="control-label form-label">Security Code</label>
<input asp-for="Order.PaymentInfo.SecurityNumber" class="form-control form-input form-input-small" />
<span asp-validation-for="Order.PaymentInfo.SecurityNumber" class="text-danger" />
</div>
</div>
</div>
<br /><br />
<div class="col-md-12 order-create-section-items">
<section>
<table class="table">
<thead>
<tr>
<th>
PRODUCT
</th>
<th>
</th>
<th>
BRAND
</th>
<th>
PRICE
</th>
<th>
QUANTITY
</th>
<th>
FINAL PRICE
</th>
</tr>
</thead>
<tbody>
@await Component.InvokeAsync("Cart")
</tbody>
</table>
@await Component.InvokeAsync("CartList", new { user = await UserManager.GetUserAsync(User) })
</section>
</div>
<br /><br /><br /><br /><br /><br />
<div class="form-group">
<div class="col-md-offset-8 col-md-4">
@*<input type="submit" value="[ PLACE ORDER ]" class="btn btn-default btn-brand" />*@
<a asp-controller="Order" asp-action="Index" class="btn btn-default btn-brand">[ PLACE ORDER ]</a>
<input type="submit" value="[ PLACE ORDER ]" class="btn btn-default btn-brand btn-cart" />
</div>
</div>
<br /><br /><br /><br /><br /><br />
</form>
</div>
@section Scripts {


+ 84
- 0
src/Web/WebMVC/Views/Order/Detail.cshtml View File

@ -0,0 +1,84 @@
@model Microsoft.eShopOnContainers.WebMVC.Models.Order
@inject UserManager<ApplicationUser> UserManager
@{
ViewData["Title"] = "Order Detail";
}
<div class="brand-header-block">
<ul class="container">
<li class="brand-header-back"><a asp-area="" asp-controller="Catalog" asp-action="Index">Back to list</a></li>
</ul>
</div>
<div class="container order-detail-container">
<div class="row">
<div class="col-sm-3">
<span>ORDER NUMBER</span><br />
<span>@Model.OrderNumber</span>
</div>
<div class="col-sm-3">
<span>DATE</span><br />
<span>@Model.OrderDate</span>
</div>
<div class="col-sm-3">
<span>TOTAL</span><br />
<span>$ @Model.Total()</span>
</div>
<div class="col-sm-3">
<span>STATUS</span><br />
<span>@Model.State</span>
</div>
</div>
<div class="row order-detail-section">
<div class="col-sm-3">
<span>SHIPING ADDRESS</span><br />
<span>@Model.ShippingAddress.Street</span><br />
<span>@Model.ShippingAddress.City</span><br />
@*<span>@Model.ShippingAddress.ZipCode</span><br />*@
<span>@Model.ShippingAddress.Country</span><br />
</div>
</div>
<div>
<div class="row order-detail-section"><div class="col-sm-3">ORDER DETAILS</div></div>
<section>
<table class="table">
<tbody>
@for (int i = 0; i < Model.OrderItems.Count; i++)
{
var item = Model.OrderItems[i];
<tr>
<td class="cart-product-column"><img class="cart-product-image" src="@item.PictureUrl" /></td>
<td class="cart-product-column">@item.ProductName</td>
<td class="cart-product-column">ROSLYN</td>
<td class="cart-product-column">$ @item.UnitPrice</td>
<td class="cart-product-column">@item.Quantity</td>
<td class="cart-product-column cart-total-value">$ @(item.Quantity * item.UnitPrice)</td>
</tr>
}
</tbody>
</table>
<div class="row">
<div class="col-sm-6">
</div>
</div>
</section>
</div>
<div class="col-md-offset-9 col-md-3">
@*<input type="submit"
class="btn btn-default cart-refresh-button"
value=""
name="action" />*@
<div class="order-section-total">
@*<div class="cart-subtotal-label"><span>SUBTOTAL</span></div>
<div class="cart-subtotal-value"><span>$ @Model.Total()</span></div>
<div class="cart-subtotal-label"><span>TAX</span></div>
<div class="cart-subtotal-value"><span>$ 4.20</span></div>*@
<div class="cart-total-label"><span>TOTAL</span></div>
<div class="cart-total-value"><span>$ @Model.Total()</span></div>
</div>
</div>
</div>

+ 11
- 15
src/Web/WebMVC/Views/Order/Index.cshtml View File

@ -1,29 +1,28 @@
@model IEnumerable<Microsoft.eShopOnContainers.WebMVC.Models.Order>
@{
ViewData["Title"] = "View";
ViewData["Title"] = "My Orders";
}
<div class="brand-header-block">
<ul class="container">
<li class="brand-header-back"><a asp-area="" asp-controller="Home" asp-action="Index">Back to home</a></li>
<li class="brand-header-back"><a asp-area="" asp-controller="Catalog" asp-action="Index">Back to home</a></li>
</ul>
</div>
<div class="container cart-index-container">
<div class="container order-index-container">
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.OrderNumber)
ORDER NUMBER
</th>
<th>
@Html.DisplayNameFor(model => model.OrderDate)
@*@Html.DisplayNameFor(model => model.SequenceNumber)*@
DATE
</th>
<th>
@Html.DisplayNameFor(model => model.BuyerId)
TOTAL
</th>
<th>
@Html.DisplayNameFor(model => model.OrderDate)
STATUS
</th>
<th></th>
</tr>
@ -36,18 +35,15 @@
</td>
<td>
@Html.DisplayFor(modelItem => item.OrderDate)
@*@Html.DisplayFor(modelItem => item.SequenceNumber)*@
</td>
<td>
@Html.DisplayFor(modelItem => item.BuyerId)
$ @item.Total()
</td>
<td>
@Html.DisplayFor(modelItem => item.OrderDate)
@Html.DisplayFor(modelItem => item.State)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
@Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
@Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
<td class="order-detail-button">
<a asp-controller="Order" asp-action="Detail" asp-route-orderId="@item.Id">Detail</a>
</td>
</tr>
}


+ 58
- 15
src/Web/WebMVC/Views/Shared/Components/CartList/Default.cshtml View File

@ -4,22 +4,65 @@
ViewData["Title"] = "My Cart";
}
@for (int i = 0; i < Model.Items.Count; i++)
{
var item = Model.Items[i];
<div class="col-md-12">
<section>
<table class="table">
<thead>
<tr>
<th class="cart-product-column">
PRODUCT
</th>
<th>
<tr>
<td class="cart-product-column"><img class="cart-product-image" src="@item.PictureUrl" /></td>
<td class="cart-product-column">@item.ProductName</td>
<td class="cart-product-column">ROSLYN</td>
<td class="cart-product-column">$ @item.UnitPrice</td>
<td class="cart-product-column">
<input type="hidden" name="@("quantities[" + i +"].Key")" value="@item.Id" />
<input type="number" name="@("quantities[" + i +"].Value")" value="@item.Quantity" />
</td>
<td class="cart-product-column cart-total-value">$ @(item.Quantity * item.UnitPrice)</td>
</tr>
}
</th>
<th>
BRAND
</th>
<th>
PRICE
</th>
<th>
QUANTITY
</th>
<th>
COST
</th>
</tr>
</thead>
<tbody>
@for (int i = 0; i < Model.Items.Count; i++)
{
var item = Model.Items[i];
<tr>
<td class="cart-product-column"><img class="cart-product-image" src="@item.PictureUrl" /></td>
<td class="cart-product-column">@item.ProductName</td>
<td class="cart-product-column">ROSLYN</td>
<td class="cart-product-column">$ @item.UnitPrice</td>
<td class="cart-product-column">
<input type="hidden" name="@("quantities[" + i +"].Key")" value="@item.Id" />
<input type="number" name="@("quantities[" + i +"].Value")" value="@item.Quantity" />
</td>
<td class="cart-product-column cart-total-value">$ @(item.Quantity * item.UnitPrice)</td>
</tr>
}
</tbody>
</table>
</section>
</div>
<div class="col-md-offset-8 col-md-4">
<input type="submit"
class="btn btn-default cart-refresh-button"
value=""
name="action" />
<div class="cart-section-total">
@*<div class="cart-subtotal-label"><span>SUBTOTAL</span></div>
<div class="cart-subtotal-value"><span>$ @Model.Total()</span></div>
<div class="cart-subtotal-label"><span>TAX</span></div>
<div class="cart-subtotal-value"><span>$ 4.20</span></div>*@
<div class="cart-total-label"><span>TOTAL</span></div>
<div class="cart-total-value"><span>$ @Model.Total()</span></div>
</div>
</div>

+ 1
- 1
src/Web/WebMVC/Views/Shared/_LoginPartial.cshtml View File

@ -12,7 +12,7 @@
<div class="fr login-user">
<span>@UserManager.GetUserName(User)<i class="down-arrow"></i></span>
<div class="login-user-dropdown-content">
<a href="#">MY ORDERS<i class="myorders-icon"></i></a>
<a asp-controller="Order" asp-action="Index">MY ORDERS<i class="myorders-icon"></i></a>
<a href="javascript:document.getElementById('logoutForm').submit()">LOG OUT<i class="logout-icon"></i></a>
</div>
</div>


+ 88
- 5
src/Web/WebMVC/wwwroot/css/site.css View File

@ -107,7 +107,7 @@ select::-ms-expand {
border-radius: 50%;
width: 18px;
height: 18px;
font-size: 13px;
font-size: 12px;
cursor: pointer;
}
@ -512,6 +512,13 @@ form .col-md-4 {
margin-bottom: 30px;
}
.order-create-container {
min-height: 70vh;
padding-top: 40px;
margin-bottom: 30px;
padding-left: 30px;
}
.cart-product-column {
max-width: 120px;
text-transform: uppercase;
@ -538,6 +545,7 @@ form .col-md-4 {
.cart-total-value {
font-size: 28px;
color: #00a69c;
text-align: left;
}
.cart-product-image {
@ -546,7 +554,7 @@ form .col-md-4 {
.cart-section-total {
margin-bottom: 5px;
margin-left: 185px;
margin-left: 175px;
text-align: left;
}
@ -557,7 +565,19 @@ form .col-md-4 {
.cart-refresh-button {
margin-top:0;
}
background-image: url('../images/refresh.svg');
color: white;
font-size: 8px;
width: 40px;
margin-top: 10px;
height: 40px;
background-color:transparent;
border:none;
}
.cart-refresh-button:hover {
background-color:transparent;
}
.input-validation-error {
border: 1px solid #fb0d0d;
@ -584,13 +604,72 @@ form .col-md-4 {
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: -30px;
margin-left: -45px;
width: 102%;
}
.order-detail-button {
}
.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 {
@ -656,7 +735,7 @@ form .col-md-4 {
}
.login-user-dropdown-content a:hover {
color: #f1f1f1;
color: #83d01b;
}
.es-header {
@ -706,6 +785,10 @@ form .col-md-4 {
border-bottom:1px solid #ddd;
}
.table th {
text-transform: uppercase;
}
/* Hide/rearrange for smaller screens */
@media screen and (max-width: 767px) {


+ 44
- 0
src/Web/WebMVC/wwwroot/images/refresh.svg View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 259.244 259.244" style="enable-background:new 0 0 259.244 259.244;" xml:space="preserve">
<g>
<path style="fill:#3DB39E;" d="M248.348,129.3h-15.849C232.41,65.277,180.831,13.394,117.202,13.394
c-31.841,0-60.661,12.998-81.534,33.996C14.017,68.549,0.25,97.092,0.036,129.3H0l0.018,0.331L0,130.033h0.036
c0.393,63.853,51.758,115.816,115.19,115.816c31.841,0,60.661-13.007,81.534-34.049l-25.852-24.931
c-14.178,14.303-34.058,23.027-55.682,23.135c-44.401,0.206-79.201-36.49-79.201-80.122c-0.107-22.893,10.092-42.908,25.486-57.595
c14.186-14.285,34.058-23.001,55.691-23.108c44.41-0.206,79.201,36.445,79.201,79.997v0.125h-15.661
c-9.708,0-13.668,6.499-8.814,14.41l33.799,33.433c7.732,7.732,9.967,7.661,17.646,0l33.799-33.433
C262.025,135.781,258.056,129.3,248.348,129.3z"/>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

+ 1
- 14
src/Web/WebMVC/wwwroot/js/site.js View File

@ -1,14 +1 @@
// Write your Javascript code.
$('#item_Quantity').change(function () {
$('.cart-refresh-button').removeClass('is-disabled');
});
function checkoutCart(){
$('#cartForm').attr('action', '/Cart?option=checkout');
$('#cartForm').submit();
}
function refreshCart() {
$('#cartForm').attr('action','/Cart?option=refresh');
$('#cartForm').submit();
}
// Write your Javascript code.

Loading…
Cancel
Save