@ -0,0 +1,24 @@ | |||
namespace Microsoft.eShopOnContainers.Services.Marketing.API.ViewModel | |||
{ | |||
using System.Collections.Generic; | |||
public class PaginatedItemsViewModel<TEntity> where TEntity : class | |||
{ | |||
public int PageIndex { get; private set; } | |||
public int PageSize { get; private set; } | |||
public long Count { get; private set; } | |||
public IEnumerable<TEntity> Data { get; private set; } | |||
public PaginatedItemsViewModel(int pageIndex, int pageSize, long count, IEnumerable<TEntity> data) | |||
{ | |||
this.PageIndex = pageIndex; | |||
this.PageSize = pageSize; | |||
this.Count = count; | |||
this.Data = data; | |||
} | |||
} | |||
} |
@ -1 +0,0 @@ | |||
|
@ -1,89 +0,0 @@ | |||
import { Injectable } from '@angular/core'; | |||
import { Response } from '@angular/http'; | |||
import { DataService } from '../shared/services/data.service'; | |||
import { IOrder } from '../shared/models/order.model'; | |||
import { IOrderItem } from '../shared/models/orderItem.model'; | |||
import { IOrderDetail } from "../shared/models/order-detail.model"; | |||
import { SecurityService } from '../shared/services/security.service'; | |||
import { ConfigurationService } from '../shared/services/configuration.service'; | |||
import 'rxjs/Rx'; | |||
import { Observable } from 'rxjs/Observable'; | |||
import 'rxjs/add/observable/throw'; | |||
import { Observer } from 'rxjs/Observer'; | |||
import 'rxjs/add/operator/map'; | |||
@Injectable() | |||
export class CampaignService { | |||
private marketingUrl: string = ''; | |||
constructor(private service: DataService, private identityService: SecurityService, private configurationService: ConfigurationService) { | |||
if (this.configurationService.isReady) | |||
this.marketingUrl = this.configurationService.serverSettings.marketingUrl; | |||
else | |||
this.configurationService.settingsLoaded$.subscribe(x => this.marketingUrl = this.configurationService.serverSettings.marketingUrl); | |||
} | |||
getOrders(): Observable<IOrder[]> { | |||
let url = this.marketingUrl + '/api/v1/campaigns/'; | |||
return this.service.get(url).map((response: Response) => { | |||
return response.json(); | |||
}); | |||
} | |||
getOrder(id: number): Observable<IOrderDetail> { | |||
let url = this.marketingUrl + '/api/v1/campaigns/' + id; | |||
return this.service.get(url).map((response: Response) => { | |||
return response.json(); | |||
}); | |||
} | |||
mapOrderAndIdentityInfoNewOrder(): IOrder { | |||
let order = <IOrder>{}; | |||
let basket = this.basketService.basket; | |||
let identityInfo = this.identityService.UserData; | |||
console.log(basket); | |||
console.log(identityInfo); | |||
// Identity data mapping: | |||
order.street = identityInfo.address_street; | |||
order.city = identityInfo.address_city; | |||
order.country = identityInfo.address_country; | |||
order.state = identityInfo.address_state; | |||
order.zipcode = identityInfo.address_zip_code; | |||
order.cardexpiration = identityInfo.card_expiration; | |||
order.cardnumber = identityInfo.card_number; | |||
order.cardsecuritynumber = identityInfo.card_security_number; | |||
order.cardtypeid = identityInfo.card_type; | |||
order.cardholdername = identityInfo.card_holder; | |||
order.total = 0; | |||
order.expiration = identityInfo.card_expiration; | |||
// basket data mapping: | |||
order.orderItems = new Array<IOrderItem>(); | |||
basket.items.forEach(x => { | |||
let item: IOrderItem = <IOrderItem>{}; | |||
item.pictureurl = x.pictureUrl; | |||
item.productId = +x.productId; | |||
item.productname = x.productName; | |||
item.unitprice = x.unitPrice; | |||
item.units = x.quantity; | |||
order.total += (item.unitprice * item.units); | |||
order.orderItems.push(item); | |||
}); | |||
order.buyer = basket.buyerId; | |||
return order; | |||
} | |||
} | |||
@ -0,0 +1,17 @@ | |||
<esh-header url="/campaigns">Back to campaigns</esh-header> | |||
<div class="container"> | |||
<div class="esh-campaign_detail"> | |||
<div class="card esh-campaigns-items"> | |||
<img class="card-img-top" src="{{campaign.pictureUri}}" alt="{{campaign.name}}"> | |||
<div class="card-block"> | |||
<h4 class="card-title">{{campaign.name}}</h4> | |||
<p class="card-text">{{campaign.description}}</p> | |||
<p class="card-text"> | |||
<small class="text-muted"> | |||
From {{campaign.from | date}} Until {{campaign.to | date}} | |||
</small> | |||
</p> | |||
</div> | |||
</div> | |||
</div> | |||
</div> |
@ -0,0 +1,57 @@ | |||
@import '../../variables'; | |||
.esh-campaign_detail { | |||
min-height: 80vh; | |||
margin-top: 1rem; | |||
&-section { | |||
padding: 1rem 0; | |||
&--right { | |||
text-align: right; | |||
} | |||
} | |||
&-titles { | |||
padding-bottom: 1rem; | |||
padding-top: 2rem; | |||
} | |||
&-title { | |||
text-transform: uppercase; | |||
} | |||
&-items { | |||
&--border { | |||
border-bottom: $border-light solid $color-foreground-bright; | |||
padding: .5rem 0; | |||
&:last-of-type { | |||
border-color: transparent; | |||
} | |||
} | |||
} | |||
$item-height: 8rem; | |||
&-item { | |||
font-size: $font-size-m; | |||
font-weight: $font-weight-semilight; | |||
&--middle { | |||
line-height: $item-height; | |||
@media screen and (max-width: $media-screen-s) { | |||
line-height: $font-size-m; | |||
} | |||
} | |||
&--mark { | |||
color: $color-secondary; | |||
} | |||
} | |||
&-image { | |||
height: $item-height; | |||
} | |||
} |
@ -0,0 +1,30 @@ | |||
import { Component, OnInit } from '@angular/core'; | |||
import { CampaignsService } from '../campaigns.service'; | |||
import { ICampaignItem } from '../../shared/models/campaignItem.model'; | |||
import { ActivatedRoute } from '@angular/router'; | |||
@Component({ | |||
selector: 'esh-campaigns_detail', | |||
styleUrls: ['./campaigns-detail.component.scss'], | |||
templateUrl: './campaigns-detail.component.html' | |||
}) | |||
export class CampaignsDetailComponent implements OnInit { | |||
public campaign: ICampaignItem = <ICampaignItem>{}; | |||
constructor(private service: CampaignsService, private route: ActivatedRoute) { } | |||
ngOnInit() { | |||
this.route.params.subscribe(params => { | |||
let id = +params['id']; // (+) converts string 'id' to a number | |||
this.getCampaign(id); | |||
}); | |||
} | |||
getCampaign(id: number) { | |||
this.service.getCampaign(id).subscribe(campaign => { | |||
this.campaign = campaign; | |||
console.log('campaign retrieved: ' + campaign.id); | |||
console.log(this.campaign); | |||
}); | |||
} | |||
} |
@ -0,0 +1,30 @@ | |||
<esh-header url="/catalog">Back to catalog</esh-header> | |||
<div class="container"> | |||
<div *ngIf="campaigns?.data?.length > 0"> | |||
<esh-pager [model]="paginationInfo" (changed)="onPageChanged($event)"></esh-pager> | |||
<div class="card-group esh-campaign-items row"> | |||
<div class="esh-campaign-item col-md-4" | |||
*ngFor="let item of campaigns.data"> | |||
<div class="card-block"> | |||
<h4 class="card-title esh-campaigns-name">{{item.name}}</h4> | |||
<img class="card-img-top esh-campaigns-thumbnail" src="{{item.pictureUri}}" alt="{{item.name}}"> | |||
<input [ngClass]="{'esh-campaign-button': true}" type="submit" value="More details" routerLink="/campaigns/{{item.id}}"> | |||
</div> | |||
<div class="card-footer"> | |||
<small class="text-muted"> | |||
From {{item.from | date }} To {{item.to | date }} | |||
</small> | |||
</div> | |||
</div> | |||
</div> | |||
<esh-pager [model]="paginationInfo" (changed)="onPageChanged($event)"></esh-pager> | |||
</div> | |||
<div *ngIf="campaigns?.data?.length == 0"> | |||
<span>THERE ARE NO RESULTS THAT MATCH YOUR SEARCH</span> | |||
</div> | |||
</div> | |||
@ -0,0 +1,65 @@ | |||
@import '../variables'; | |||
.esh-campaign { | |||
$banner-height: 260px; | |||
&-title { | |||
position: relative; | |||
top: $banner-height / 3.5; | |||
} | |||
&-items { | |||
margin-top: 1rem; | |||
} | |||
&-item { | |||
margin-bottom: 1.5rem; | |||
text-align: center; | |||
width: 33%; | |||
display: inline-block; | |||
float: none !important; | |||
@media screen and (max-width: $media-screen-m) { | |||
width: 50%; | |||
} | |||
@media screen and (max-width: $media-screen-s) { | |||
width: 100%; | |||
} | |||
} | |||
&-thumbnail { | |||
max-width: 370px; | |||
width: 100%; | |||
} | |||
&-button { | |||
background-color: $color-secondary; | |||
border: 0; | |||
color: $color-foreground-brighter; | |||
cursor: pointer; | |||
font-size: $font-size-m; | |||
height: 3rem; | |||
margin-top: 1rem; | |||
transition: all $animation-speed-default; | |||
width: 80%; | |||
&.is-disabled { | |||
opacity: .5; | |||
pointer-events: none; | |||
} | |||
&:hover { | |||
background-color: $color-secondary-darker; | |||
transition: all $animation-speed-default; | |||
} | |||
} | |||
&-name { | |||
font-size: $font-size-m; | |||
font-weight: $font-weight-semilight; | |||
margin-top: .5rem; | |||
text-align: center; | |||
text-transform: uppercase; | |||
} | |||
} |
@ -0,0 +1,49 @@ | |||
import { Component, OnInit } from '@angular/core'; | |||
import { CampaignsService } from './campaigns.service'; | |||
import { ICampaign } from '../shared/models/campaign.model'; | |||
import { IPager } from '../shared/models/pager.model'; | |||
import { ConfigurationService } from '../shared/services/configuration.service'; | |||
@Component({ | |||
selector: 'esh-campaigns', | |||
styleUrls: ['./campaigns.component.scss'], | |||
templateUrl: './campaigns.component.html' | |||
}) | |||
export class CampaignsComponent implements OnInit { | |||
private interval = null; | |||
paginationInfo: IPager; | |||
campaigns: ICampaign; | |||
constructor(private service: CampaignsService, private configurationService: ConfigurationService) { } | |||
ngOnInit() { | |||
if (this.configurationService.isReady) { | |||
this.getCampaigns(9, 0) | |||
} else { | |||
this.configurationService.settingsLoaded$.subscribe(x => { | |||
this.getCampaigns(9, 0); | |||
}); | |||
} | |||
} | |||
onPageChanged(value: any) { | |||
console.log('campaigns pager event fired' + value); | |||
//event.preventDefault(); | |||
this.paginationInfo.actualPage = value; | |||
this.getCampaigns(this.paginationInfo.itemsPage, value); | |||
} | |||
getCampaigns(pageSize: number, pageIndex: number) { | |||
this.service.getCampaigns(pageIndex, pageSize).subscribe(campaigns => { | |||
this.campaigns = campaigns; | |||
this.paginationInfo = { | |||
actualPage : campaigns.pageIndex, | |||
itemsPage : campaigns.pageSize, | |||
totalItems : campaigns.count, | |||
totalPages: Math.ceil(campaigns.count / campaigns.pageSize), | |||
items: campaigns.pageSize | |||
}; | |||
}); | |||
} | |||
} | |||
@ -0,0 +1,15 @@ | |||
import { NgModule } from '@angular/core'; | |||
import { BrowserModule } from '@angular/platform-browser'; | |||
import { SharedModule } from '../shared/shared.module'; | |||
import { CampaignsComponent } from './campaigns.component'; | |||
import { CampaignsDetailComponent } from './campaigns-detail/campaigns-detail.component'; | |||
import { CampaignsService } from './campaigns.service'; | |||
import { Header } from '../shared/components/header/header'; | |||
@NgModule({ | |||
imports: [BrowserModule, SharedModule], | |||
declarations: [CampaignsComponent, CampaignsDetailComponent], | |||
providers: [CampaignsService] | |||
}) | |||
export class CampaignsModule { } |
@ -0,0 +1,52 @@ | |||
import { Injectable } from '@angular/core'; | |||
import { Response } from '@angular/http'; | |||
import { DataService } from '../shared/services/data.service'; | |||
import { ICampaign } from '../shared/models/campaign.model'; | |||
import { ICampaignItem } from '../shared/models/campaignItem.model'; | |||
import { SecurityService } from '../shared/services/security.service'; | |||
import { ConfigurationService } from '../shared/services/configuration.service'; | |||
import 'rxjs/Rx'; | |||
import { Observable } from 'rxjs/Observable'; | |||
import 'rxjs/add/observable/throw'; | |||
import { Observer } from 'rxjs/Observer'; | |||
import 'rxjs/add/operator/map'; | |||
@Injectable() | |||
export class CampaignsService { | |||
private marketingUrl: string = ''; | |||
private buyerId: string = ''; | |||
constructor(private service: DataService, private identityService: SecurityService, private configurationService: ConfigurationService) { | |||
if (this.identityService.IsAuthorized) { | |||
if (this.identityService.UserData) { | |||
this.buyerId = this.identityService.UserData.sub; | |||
} | |||
} | |||
if (this.configurationService.isReady) | |||
this.marketingUrl = this.configurationService.serverSettings.marketingUrl; | |||
else | |||
this.configurationService.settingsLoaded$.subscribe(x => this.marketingUrl = this.configurationService.serverSettings.marketingUrl); | |||
} | |||
getCampaigns(pageIndex: number, pageSize: number): Observable<ICampaign> { | |||
let url = this.marketingUrl + '/api/v1/campaigns/user/' + this.buyerId; | |||
url = url + '?pageIndex=' + pageIndex + '&pageSize=' + pageSize; | |||
return this.service.get(url).map((response: Response) => { | |||
return response.json(); | |||
}); | |||
} | |||
getCampaign(id: number): Observable<ICampaignItem> { | |||
let url = this.marketingUrl + '/api/v1/campaigns/' + id; | |||
return this.service.get(url).map((response: Response) => { | |||
return response.json(); | |||
}); | |||
} | |||
} | |||
@ -0,0 +1,9 @@ | |||
import {ICampaignItem} from './campaignItem.model'; | |||
export interface ICampaign { | |||
data: ICampaignItem[]; | |||
pageIndex: number; | |||
pageSize: number; | |||
count: number; | |||
} | |||
@ -0,0 +1,8 @@ | |||
export interface ICampaignItem { | |||
id: number; | |||
name: string; | |||
description: string; | |||
from: Date; | |||
to: Date; | |||
pictureUri: string; | |||
} |