@ -1,100 +0,0 @@ | |||
namespace Microsoft.eShopOnContainers.WebMVC.Controllers | |||
{ | |||
using AspNetCore.Authorization; | |||
using AspNetCore.Mvc; | |||
using global::WebMVC.Services.ModelDTOs; | |||
using global::WebMVC.Services; | |||
using global::WebMVC.ViewModels; | |||
using Microsoft.Extensions.Options; | |||
using Services; | |||
using System; | |||
using System.Threading.Tasks; | |||
using ViewModels; | |||
using ViewModels.Pagination; | |||
using Microsoft.AspNetCore.Authentication.OpenIdConnect; | |||
[Authorize(AuthenticationSchemes = OpenIdConnectDefaults.AuthenticationScheme)] | |||
public class CampaignsController : Controller | |||
{ | |||
private readonly ICampaignService _campaignService; | |||
private readonly ILocationService _locationService; | |||
private readonly AppSettings _settings; | |||
public CampaignsController(ICampaignService campaignService, ILocationService locationService, IOptionsSnapshot<AppSettings> settings) | |||
{ | |||
_campaignService = campaignService; | |||
_settings = settings.Value; | |||
_locationService = locationService; | |||
} | |||
public async Task<IActionResult> Index(int page = 0, int pageSize = 10) | |||
{ | |||
var campaignList = await _campaignService.GetCampaigns(pageSize, page); | |||
if(campaignList is null) | |||
{ | |||
return View(); | |||
} | |||
var totalPages = (int) Math.Ceiling((decimal) campaignList.Count / pageSize); | |||
var vm = new CampaignViewModel | |||
{ | |||
CampaignItems = campaignList.Data, | |||
PaginationInfo = new PaginationInfo | |||
{ | |||
ActualPage = page, | |||
ItemsPerPage = campaignList.Data.Count, | |||
TotalItems = campaignList.Count, | |||
TotalPages = totalPages, | |||
Next = page == totalPages - 1 ? "is-disabled" : "", | |||
Previous = page == 0 ? "is-disabled" : "" | |||
} | |||
}; | |||
ViewBag.IsCampaignDetailFunctionActive = _settings.ActivateCampaignDetailFunction; | |||
return View(vm); | |||
} | |||
public async Task<IActionResult> Details(int id) | |||
{ | |||
var campaignDto = await _campaignService.GetCampaignById(id); | |||
if (campaignDto is null) | |||
{ | |||
return NotFound(); | |||
} | |||
var campaign = new CampaignItem | |||
{ | |||
Id = campaignDto.Id, | |||
Name = campaignDto.Name, | |||
Description = campaignDto.Description, | |||
From = campaignDto.From, | |||
To = campaignDto.To, | |||
PictureUri = campaignDto.PictureUri | |||
}; | |||
return View(campaign); | |||
} | |||
[HttpPost] | |||
public async Task<IActionResult> CreateNewUserLocation(CampaignViewModel model) | |||
{ | |||
if (ModelState.IsValid) | |||
{ | |||
var location = new LocationDTO() | |||
{ | |||
Longitude = model.Lon, | |||
Latitude = model.Lat | |||
}; | |||
await _locationService.CreateOrUpdateUserLocation(location); | |||
return RedirectToAction(nameof(Index)); | |||
} | |||
return View(nameof(Index), model); | |||
} | |||
} | |||
} |
@ -1,49 +0,0 @@ | |||
namespace Microsoft.eShopOnContainers.WebMVC.Services | |||
{ | |||
using global::WebMVC.Infrastructure; | |||
using Microsoft.Extensions.Logging; | |||
using Microsoft.Extensions.Options; | |||
using Newtonsoft.Json; | |||
using System.Net.Http; | |||
using System.Threading.Tasks; | |||
using ViewModels; | |||
public class CampaignService : ICampaignService | |||
{ | |||
private readonly IOptions<AppSettings> _settings; | |||
private readonly HttpClient _httpClient; | |||
private readonly ILogger<CampaignService> _logger; | |||
private readonly string _remoteServiceBaseUrl; | |||
public CampaignService(IOptions<AppSettings> settings, HttpClient httpClient, ILogger<CampaignService> logger) | |||
{ | |||
_settings = settings; | |||
_httpClient = httpClient; | |||
_logger = logger; | |||
_remoteServiceBaseUrl = $"{_settings.Value.MarketingUrl}/m/api/v1/campaigns/"; | |||
} | |||
public async Task<Campaign> GetCampaigns(int pageSize, int pageIndex) | |||
{ | |||
var uri = API.Marketing.GetAllCampaigns(_remoteServiceBaseUrl, pageSize, pageIndex); | |||
var responseString = await _httpClient.GetStringAsync(uri); | |||
var response = JsonConvert.DeserializeObject<Campaign>(responseString); | |||
return response; | |||
} | |||
public async Task<CampaignItem> GetCampaignById(int id) | |||
{ | |||
var uri = API.Marketing.GetAllCampaignById(_remoteServiceBaseUrl, id); | |||
var responseString = await _httpClient.GetStringAsync(uri); | |||
var response = JsonConvert.DeserializeObject<CampaignItem>(responseString); | |||
return response; | |||
} | |||
} | |||
} |
@ -1,13 +0,0 @@ | |||
namespace Microsoft.eShopOnContainers.WebMVC.Services | |||
{ | |||
using System.Collections.Generic; | |||
using System.Threading.Tasks; | |||
using ViewModels; | |||
public interface ICampaignService | |||
{ | |||
Task<Campaign> GetCampaigns(int pageSize, int pageIndex); | |||
Task<CampaignItem> GetCampaignById(int id); | |||
} | |||
} |
@ -1,10 +0,0 @@ | |||
using System.Threading.Tasks; | |||
using WebMVC.Services.ModelDTOs; | |||
namespace WebMVC.Services | |||
{ | |||
public interface ILocationService | |||
{ | |||
Task CreateOrUpdateUserLocation(LocationDTO location); | |||
} | |||
} |
@ -1,38 +0,0 @@ | |||
using Microsoft.eShopOnContainers.WebMVC; | |||
using Microsoft.eShopOnContainers.WebMVC.Services; | |||
using Microsoft.Extensions.Logging; | |||
using Microsoft.Extensions.Options; | |||
using Newtonsoft.Json; | |||
using System.Net.Http; | |||
using System.Threading.Tasks; | |||
using WebMVC.Infrastructure; | |||
using WebMVC.Services.ModelDTOs; | |||
namespace WebMVC.Services | |||
{ | |||
public class LocationService : ILocationService | |||
{ | |||
private readonly IOptions<AppSettings> _settings; | |||
private readonly HttpClient _httpClient; | |||
private readonly ILogger<CampaignService> _logger; | |||
private readonly string _remoteServiceBaseUrl; | |||
public LocationService(HttpClient httpClient, IOptions<AppSettings> settings, ILogger<CampaignService> logger) | |||
{ | |||
_httpClient = httpClient; | |||
_settings = settings; | |||
_logger = logger; | |||
_remoteServiceBaseUrl = $"{_settings.Value.MarketingUrl}/l/api/v1/locations/"; | |||
} | |||
public async Task CreateOrUpdateUserLocation(LocationDTO location) | |||
{ | |||
var uri = API.Locations.CreateOrUpdateUserLocation(_remoteServiceBaseUrl); | |||
var locationContent = new StringContent(JsonConvert.SerializeObject(location), System.Text.Encoding.UTF8, "application/json"); | |||
var response = await _httpClient.PostAsync(uri, locationContent); | |||
response.EnsureSuccessStatusCode(); | |||
} | |||
} | |||
} |
@ -1,20 +0,0 @@ | |||
namespace WebMVC.ViewModels | |||
{ | |||
using System.Collections.Generic; | |||
using Microsoft.eShopOnContainers.WebMVC.ViewModels; | |||
using Microsoft.eShopOnContainers.WebMVC.ViewModels.Pagination; | |||
using WebMVC.ViewModels.Annotations; | |||
using Newtonsoft.Json; | |||
using System.ComponentModel.DataAnnotations; | |||
public class CampaignViewModel | |||
{ | |||
public IEnumerable<CampaignItem> CampaignItems { get; set; } | |||
public PaginationInfo PaginationInfo { get; set; } | |||
[LongitudeCoordinate, Required] | |||
public double Lon { get; set; } = -122.315752; | |||
[LatitudeCoordinate, Required] | |||
public double Lat { get; set; } = 47.604610; | |||
} | |||
} |
@ -1,31 +0,0 @@ | |||
@model CampaignItem | |||
@{ | |||
ViewData["Title"] = "Campaign details"; | |||
var headerList= new List<Header>() { | |||
new Header() { Controller = "Catalog", Text = "Back to catalog" }, | |||
new Header() { Controller = "Campaigns", Text = "Back to Campaigns" } }; | |||
} | |||
<section class="esh-campaigns-hero"> | |||
<div class="container"> | |||
<img class="esh-campaigns-title" src="~/images/main_banner_text.png" /> | |||
</div> | |||
</section> | |||
<partial name="_Header" model="headerList" /> | |||
<div class="container"> | |||
<div class="card esh-campaigns-items"> | |||
<img class="card-img-top" src="@Model.PictureUri" alt="Card image cap"> | |||
<div class="card-body"> | |||
<h4 class="card-title">@Model.Name</h4> | |||
<p class="card-text">@Model.Description</p> | |||
</div> | |||
<div class="card-footer"> | |||
<small class="text-muted"> | |||
From @Model.From.ToString("MMMM dd, yyyy") until @Model.To.ToString("MMMM dd, yyyy") | |||
</small> | |||
</div> | |||
</div> | |||
</div> |
@ -1,79 +0,0 @@ | |||
@model WebMVC.ViewModels.CampaignViewModel | |||
@{ | |||
ViewData["Title"] = "Campaigns"; | |||
var headerList= new List<Header>() { | |||
new Header() { Controller = "Catalog", Text = "Back to catalog" } }; | |||
} | |||
<section class="esh-campaigns-hero"> | |||
<div class="container"> | |||
<img class="esh-campaigns-title" src="~/images/main_banner_text.png" /> | |||
</div> | |||
</section> | |||
<partial name="_Header" model="headerList" /> | |||
<div class="container"> | |||
<br /> | |||
<div class="row"> | |||
@if (!ViewData.ModelState.IsValid) | |||
{ | |||
<div class="alert alert-warning"> | |||
@Html.ValidationSummary(false) | |||
</div> | |||
} | |||
<div class="col-md-12"> | |||
<div class="esh-campaigns-items" style="font-weight: 300;"> | |||
UPDATE USER LOCATION | |||
</div> | |||
<br /> | |||
<form class="form-inline" asp-action="CreateNewUserLocation" method="post"> | |||
<label class="sr-only" for="longitudeInput">Name</label> | |||
<div class="input-group mb-3"> | |||
<div class="input-group-prepend"> | |||
<span class="input-group-text" id="inputGroup-sizing-default">Lat</span> | |||
</div> | |||
<input type="text" class="form-control mb-2 mr-sm-2 mb-sm-0" id="latitudeInput" asp-for="Lat" placeholder="Latitude"> | |||
</div> | |||
<div class="input-group mb-3"> | |||
<div class="input-group-prepend"> | |||
<span class="input-group-text" id="inputGroup-sizing-default">Lon</span> | |||
</div> | |||
<input type="text" class="form-control mb-2 mr-sm-2 mb-sm-0" id="longitudeInput" asp-for="Lon" placeholder="Longitude"> | |||
</div> | |||
<div class="input-group mb-2 mr-sm-2 mb-sm-0 col-md-2"> | |||
<input type="submit" value="Update" class="btn esh-campaigns-form-button" /> | |||
</div> | |||
</form> | |||
</div> | |||
</div> | |||
<br /> | |||
@if (Model != null && Model.CampaignItems !=null && Model.CampaignItems.Any()) | |||
{ | |||
<div class="card-group esh-campaigns-items row"> | |||
@foreach (var catalogItem in Model.CampaignItems) | |||
{ | |||
<div class="esh-campaigns-item col-md-4"> | |||
<partial name="_campaign" model="catalogItem" /> | |||
</div> | |||
} | |||
</div> | |||
<partial name="_pagination" for="PaginationInfo" /> | |||
} | |||
else | |||
{ | |||
<div class="esh-campaigns-items row"> | |||
THERE ARE NO CAMPAIGNS | |||
</div> | |||
} | |||
</div> | |||
@ -1,23 +0,0 @@ | |||
@model CampaignItem | |||
<form asp-controller="Campaigns" asp-action="Details" asp-route-id="@Model.Id"> | |||
<div class="card"> | |||
<img class="card-img-top esh-campaigns-thumbnail" src="@Model.PictureUri" alt="@Model.Name"> | |||
<div class="card-body"> | |||
<h4 class="card-title esh-campaigns-name">@Model.Name</h4> | |||
@if (ViewBag.IsCampaignDetailFunctionActive == true) | |||
{ | |||
<input type="button" value="More Details" class="btn esh-campaigns-button" onClick="window.open('@Model.DetailsUri')"> | |||
} | |||
else | |||
{ | |||
<input class="esh-campaigns-button" type="submit" value="More details"> | |||
} | |||
</div> | |||
<div class="card-footer esh-campaigns-card-footer-text"> | |||
<small class="text-muted"> | |||
From @Model.From.ToString("MMMM dd, yyyy") until @Model.To.ToString("MMMM dd, yyyy") | |||
</small> | |||
</div> | |||
</div> | |||
</form> |
@ -1,32 +0,0 @@ | |||
@model Microsoft.eShopOnContainers.WebMVC.ViewModels.Pagination.PaginationInfo | |||
<div class="esh-pager"> | |||
<div class="container"> | |||
<article class="esh-pager-wrapper row"> | |||
<nav> | |||
<a class="esh-pager-item esh-pager-item--navigable @Model.Previous" | |||
id="Previous" | |||
asp-controller="Campaigns" | |||
asp-action="Index" | |||
asp-route-page="@(Model.ActualPage -1)" | |||
aria-label="Previous"> | |||
Previous | |||
</a> | |||
<span class="esh-pager-item"> | |||
Showing @Model.ItemsPerPage of @Model.TotalItems products - Page @(Model.ActualPage + 1) - @Model.TotalPages | |||
</span> | |||
<a class="esh-pager-item esh-pager-item--navigable @Model.Next" | |||
id="Next" | |||
asp-controller="Campaigns" | |||
asp-action="Index" | |||
asp-route-page="@(Model.ActualPage + 1)" | |||
aria-label="Next"> | |||
Next | |||
</a> | |||
</nav> | |||
</article> | |||
</div> | |||
</div> | |||
@ -1,116 +0,0 @@ | |||
.esh-campaigns-hero { | |||
background-image: url("../../images/main_banner.png"); | |||
background-size: cover; | |||
height: 260px; | |||
width: 100%; | |||
} | |||
.esh-campaigns-title { | |||
position: relative; | |||
top: 74.28571px; | |||
} | |||
.esh-campaigns-label::before { | |||
color: rgba(255, 255, 255, 0.5); | |||
content: attr(data-title); | |||
font-size: 0.65rem; | |||
margin-top: 0.65rem; | |||
margin-left: 0.5rem; | |||
position: absolute; | |||
text-transform: uppercase; | |||
z-index: 1; | |||
} | |||
.esh-campaigns-label::after { | |||
background-image: url("../../images/arrow-down.png"); | |||
height: 7px; | |||
content: ''; | |||
position: absolute; | |||
right: 1.5rem; | |||
top: 2.5rem; | |||
width: 10px; | |||
z-index: 1; | |||
} | |||
.esh-campaigns-items { | |||
margin-top: 1rem; | |||
} | |||
.esh-campaigns-item { | |||
text-align: center; | |||
margin-bottom: 1.5rem; | |||
width: 33%; | |||
display: inline-block; | |||
float: none !important; | |||
} | |||
@media screen and (max-width: 1024px) { | |||
.esh-campaigns-item { | |||
width: 50%; | |||
} | |||
} | |||
@media screen and (max-width: 768px) { | |||
.esh-campaigns-item { | |||
width: 100%; | |||
} | |||
} | |||
.esh-campaigns-thumbnail { | |||
max-width: 370px; | |||
width: 100%; | |||
} | |||
.esh-campaigns-button { | |||
background-color: #83D01B; | |||
border: none; | |||
color: #FFFFFF; | |||
cursor: pointer; | |||
font-size: 1rem; | |||
height: 3rem; | |||
margin-top: 1rem; | |||
transition: all 0.35s; | |||
width: 80%; | |||
} | |||
.esh-campaigns-card-footer-text { | |||
white-space: nowrap; | |||
overflow: hidden; | |||
text-overflow: ellipsis; | |||
} | |||
.esh-campaigns-form-button { | |||
background-color: #83D01B; | |||
border: none; | |||
color: #FFFFFF; | |||
cursor: pointer; | |||
font-size: 1rem; | |||
transition: all 0.35s; | |||
width: 80%; | |||
margin-top: -15px; | |||
} | |||
.esh-campaigns-button.is-disabled { | |||
opacity: .5; | |||
pointer-events: none; | |||
} | |||
.esh-campaigns-button:hover { | |||
background-color: #4a760f; | |||
transition: all 0.35s; | |||
} | |||
.esh-campaigns-name { | |||
font-size: 1rem; | |||
font-weight: 300; | |||
margin-top: .5rem; | |||
text-align: center; | |||
text-transform: uppercase; | |||
} | |||
.esh-campaigns-description { | |||
text-align: center; | |||
font-weight: 300; | |||
font-size: 14px; | |||
} | |||