From d67f5665c723dca0fa8bed4b340f8423f33e4c17 Mon Sep 17 00:00:00 2001 From: Quique Fernandez Date: Fri, 23 Dec 2016 10:51:17 +0100 Subject: [PATCH 1/4] Init orders component --- .../Client/modules/app.routes.ts | 4 +- .../Client/modules/basket/basket.routes.ts | 9 -- .../Client/modules/catalog/catalog.routes.ts | 9 -- .../modules/orders/orders.component.html | 62 +++++++++++++ .../modules/orders/orders.component.scss | 80 ++++++++++++++++ .../Client/modules/orders/orders.component.ts | 92 +++++++++++++++++++ .../Client/modules/orders/orders.module.ts | 14 +++ .../Client/modules/orders/orders.service.ts | 48 ++++++++++ 8 files changed, 299 insertions(+), 19 deletions(-) delete mode 100644 src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/basket/basket.routes.ts delete mode 100644 src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/catalog/catalog.routes.ts create mode 100644 src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.component.html create mode 100644 src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.component.scss create mode 100644 src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.component.ts create mode 100644 src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.module.ts create mode 100644 src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.service.ts diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/app.routes.ts b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/app.routes.ts index 3ce3eda19..3ab758b3f 100644 --- a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/app.routes.ts +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/app.routes.ts @@ -2,11 +2,13 @@ import { Routes, RouterModule } from '@angular/router'; import { BasketComponent } from './basket/basket.component'; import { CatalogComponent } from './catalog/catalog.component'; +import { OrdersComponent } from './orders/orders.component'; export const routes: Routes = [ { path: '', redirectTo: 'catalog', pathMatch: 'full' }, { path: 'basket', component: BasketComponent }, - { path: 'catalog', component: CatalogComponent } + { path: 'catalog', component: CatalogComponent }, + { path: 'orders', component: OrdersComponent } //Lazy async modules (angular-loader-router) and enable a router in each module. //{ // path: 'basket', loadChildren: '/basket/basket.module' }); diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/basket/basket.routes.ts b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/basket/basket.routes.ts deleted file mode 100644 index 3ed2bc003..000000000 --- a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/basket/basket.routes.ts +++ /dev/null @@ -1,9 +0,0 @@ -//import { Routes, RouterModule } from '@angular/router'; - -//import { BasketComponent } from './basket.component'; - -//const routes: Routes = [ -// { path: '', component: BasketComponent } -//]; - -//export const routing = RouterModule.forChild(routes); diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/catalog/catalog.routes.ts b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/catalog/catalog.routes.ts deleted file mode 100644 index cee81b259..000000000 --- a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/catalog/catalog.routes.ts +++ /dev/null @@ -1,9 +0,0 @@ -//import { Routes, RouterModule } from '@angular/router'; - -//import { CatalogComponent } from './catalog.component'; - -//const routes: Routes = [ -// { path: '', component: CatalogComponent } -//]; - -//export const routing = RouterModule.forChild(routes); diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.component.html b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.component.html new file mode 100644 index 000000000..6856c90b2 --- /dev/null +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.component.html @@ -0,0 +1,62 @@ +
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ PRODUCT + + + + BRAND + + PRICE + + QUANTITY + + COST +
{{item.productName}}ROSLYN$ {{item.unitPrice}} + + $ {{item.unitPrice * item.quantity}}
+
+
TOTAL
+ $ {{totalPrice}} +
+
+
+
+
+
\ No newline at end of file diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.component.scss b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.component.scss new file mode 100644 index 000000000..d748fa784 --- /dev/null +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.component.scss @@ -0,0 +1,80 @@ +@import '../_variables.scss'; + +.esh-orders { + &-header { + background-color: #00A69C; + height: 63px; + + li { + list-style: none; + display: inline; + opacity: 0.5; + margin-top: 25px; + margin-left: 10px; + float: right; + cursor: pointer; + color: white; + } + + li a { + color: white; + } + + &-back { + float: left !important; + margin-top: 20px !important; + text-transform: uppercase; + } + + li a:hover { + text-decoration: none; + } + } + + &-container { + min-height: 70vh; + padding-top: 40px; + margin-bottom: 30px; + min-width: 992px; + } + + &-product-column { + max-width: 120px; + text-transform: uppercase; + vertical-align: middle !important; + } + + &-product-image { + max-width: 210px; + } + + &-total-value { + font-size: 20px; + color: #00a69c; + } + + &-total-label { + font-size: 14px; + color: #404040; + margin-top: 10px; + } + + &-totals { + border-bottom:none!important; + } +} + +.table td { + border-top: solid 1px #ddd; +} + +.table thead th { + border: none !important; +} + + + + + + + diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.component.ts b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.component.ts new file mode 100644 index 000000000..ea1ec9fed --- /dev/null +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.component.ts @@ -0,0 +1,92 @@ +import { Component, OnInit } from '@angular/core'; +import { OrdersService } from './orders.service'; +import { ICatalog } from '../shared/models/catalog.model'; +import { ICatalogItem } from '../shared/models/catalogItem.model'; +import { ICatalogType } from '../shared/models/catalogType.model'; +import { ICatalogBrand } from '../shared/models/catalogBrand.model'; +import { IPager } from '../shared/models/pager.model'; +import { BasketWrapperService} from '../shared/services/basket.wrapper.service'; + +@Component({ + selector: 'esh-orders .orders', + styleUrls: ['./orders.component.scss'], + templateUrl: './orders.component.html' +}) +export class CatalogComponent implements OnInit { + brands: ICatalogBrand[]; + types: ICatalogType[]; + catalog: ICatalog; + brandSelected: number; + typeSelected: number; + paginationInfo: IPager; + + constructor(private service: OrdersService, private basketService: BasketWrapperService) { } + + ngOnInit() { + this.getBrands(); + this.getCatalog(10, 0); + this.getTypes(); + } + + onFilterApplied(event: any) { + event.preventDefault(); + this.getCatalog(this.paginationInfo.itemsPage, this.paginationInfo.actualPage, this.brandSelected, this.typeSelected); + } + + onBrandFilterChanged(event: any, value: number) { + event.preventDefault(); + this.brandSelected = value; + } + + onTypeFilterChanged(event: any, value: number) { + event.preventDefault(); + this.typeSelected = value; + } + + onPageChanged(value: any) { + console.log('catalog pager event fired' + value); + event.preventDefault(); + this.paginationInfo.actualPage = value; + this.getCatalog(this.paginationInfo.itemsPage, value); + } + + addToCart(item: ICatalogItem) { + this.basketService.addItemToBasket(item); + } + + getCatalog(pageSize:number, pageIndex: number, brand?: number, type?: number) { + this.service.getCatalog(pageIndex, pageSize, brand, type).subscribe(catalog => { + this.catalog = catalog; + console.log('catalog items retrieved: ' + catalog.count); + + this.paginationInfo = { + actualPage : catalog.pageIndex, + itemsPage : catalog.pageSize, + totalItems : catalog.count, + totalPages: Math.ceil(catalog.count / catalog.pageSize), + items: catalog.pageSize + }; + + console.log(this.paginationInfo); + }); + } + + getTypes() { + this.service.getTypes().subscribe(types => { + this.types = types; + let alltypes = { id: null, type: 'All' }; + this.types.unshift(alltypes); + console.log('types retrieved: ' + types.length); + }); + } + + getBrands() { + this.service.getBrands().subscribe(brands => { + this.brands = brands; + let allBrands = { id: null, brand: 'All' }; + this.brands.unshift(allBrands); + console.log('brands retrieved: ' + brands.length); + }); + } +} + diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.module.ts b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.module.ts new file mode 100644 index 000000000..ef3bec4d7 --- /dev/null +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.module.ts @@ -0,0 +1,14 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +import { SharedModule } from '../shared/shared.module'; +import { OrdersComponent } from './orders.component'; +import { OrdersService } from './orders.service'; +import { Pager } from '../shared/components/pager/pager'; + +@NgModule({ + imports: [BrowserModule, SharedModule], + declarations: [OrdersComponent], + providers: [OrdersService] +}) +export class CatalogModule { } diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.service.ts b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.service.ts new file mode 100644 index 000000000..ee57cdc86 --- /dev/null +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.service.ts @@ -0,0 +1,48 @@ +import { Injectable } from '@angular/core'; +import { Response } from '@angular/http'; + +import { DataService } from '../shared/services/data.service'; +import { ICatalog } from '../shared/models/catalog.model'; +import { ICatalogBrand } from '../shared/models/catalogBrand.model'; +import { ICatalogType } from '../shared/models/catalogType.model'; + +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 OrdersService { + private catalogUrl: string = 'http://eshopcontainers:5101/api/v1/catalog/items'; + private brandUrl: string = 'http://eshopcontainers:5101/api/v1/catalog/catalogbrands'; + private typesUrl: string = 'http://eshopcontainers:5101/api/v1/catalog/catalogtypes'; + + constructor(private service: DataService) { + } + + getCatalog(pageIndex: number, pageSize: number, brand: number, type: number): Observable { + var url = this.catalogUrl; + if (brand || type) { + url = this.catalogUrl + '/type/' + ((type) ? type.toString() : 'null') + '/brand/' + ((brand) ? brand.toString() : 'null'); + } + + url = url + '?pageIndex=' + pageIndex + '&pageSize=' + pageSize; + + return this.service.get(url).map((response: Response) => { + return response.json(); + }); + } + + getBrands(): Observable { + return this.service.get(this.brandUrl).map((response: Response) => { + return response.json(); + }); + } + + getTypes(): Observable { + return this.service.get(this.typesUrl).map((response: Response) => { + return response.json(); + }); + }; +} \ No newline at end of file From 0f3f4abbc14b765986541c98a91afa929374211b Mon Sep 17 00:00:00 2001 From: Quique Fernandez Date: Fri, 23 Dec 2016 12:14:49 +0100 Subject: [PATCH 2/4] Add orders list --- .../Client/modules/app.module.ts | 2 + .../modules/orders/orders.component.html | 51 ++++------- .../modules/orders/orders.component.scss | 11 ++- .../Client/modules/orders/orders.component.ts | 85 +++---------------- .../Client/modules/orders/orders.module.ts | 2 +- .../Client/modules/orders/orders.service.ts | 31 ++----- .../modules/shared/models/order.model.ts | 6 ++ 7 files changed, 48 insertions(+), 140 deletions(-) create mode 100644 src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/order.model.ts diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/app.module.ts b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/app.module.ts index bdad19f82..997eacbfb 100644 --- a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/app.module.ts +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/app.module.ts @@ -9,6 +9,7 @@ import { AppService } from './app.service'; import { AppComponent } from './app.component'; import { SharedModule } from './shared/shared.module'; import { CatalogModule } from './catalog/catalog.module'; +import { OrdersModule } from './orders/orders.module'; import { BasketModule } from './basket/basket.module'; @NgModule({ @@ -20,6 +21,7 @@ import { BasketModule } from './basket/basket.module'; // Only module that app module loads SharedModule.forRoot(), CatalogModule, + OrdersModule, BasketModule ], providers: [ diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.component.html b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.component.html index 6856c90b2..bbda19c23 100644 --- a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.component.html +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.component.html @@ -1,57 +1,38 @@ -
+
    -
  • Back to list
  • +
  • Back to list
-
+
- - - + - - - - - - - - - - - - - - - + + + + + diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.component.scss b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.component.scss index d748fa784..bb0ab0552 100644 --- a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.component.scss +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.component.scss @@ -1,6 +1,8 @@ @import '../_variables.scss'; .esh-orders { + min-height: 80vh; + &-header { background-color: #00A69C; height: 63px; @@ -38,13 +40,16 @@ min-width: 992px; } - &-product-column { + &-order-column { max-width: 120px; - text-transform: uppercase; vertical-align: middle !important; } - &-product-image { + &-order-link { + color: #83d01b; + } + + &-order-image { max-width: 210px; } diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.component.ts b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.component.ts index ea1ec9fed..f52509875 100644 --- a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.component.ts +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.component.ts @@ -1,91 +1,26 @@ import { Component, OnInit } from '@angular/core'; -import { OrdersService } from './orders.service'; -import { ICatalog } from '../shared/models/catalog.model'; -import { ICatalogItem } from '../shared/models/catalogItem.model'; -import { ICatalogType } from '../shared/models/catalogType.model'; -import { ICatalogBrand } from '../shared/models/catalogBrand.model'; -import { IPager } from '../shared/models/pager.model'; -import { BasketWrapperService} from '../shared/services/basket.wrapper.service'; +import { OrdersService } from './orders.service'; +import { IOrder } from '../shared/models/order.model'; @Component({ selector: 'esh-orders .orders', styleUrls: ['./orders.component.scss'], templateUrl: './orders.component.html' }) -export class CatalogComponent implements OnInit { - brands: ICatalogBrand[]; - types: ICatalogType[]; - catalog: ICatalog; - brandSelected: number; - typeSelected: number; - paginationInfo: IPager; +export class OrdersComponent implements OnInit { + orders: IOrder[]; - constructor(private service: OrdersService, private basketService: BasketWrapperService) { } + constructor(private service: OrdersService) { } ngOnInit() { - this.getBrands(); - this.getCatalog(10, 0); - this.getTypes(); + this.getOrders(); } - onFilterApplied(event: any) { - event.preventDefault(); - this.getCatalog(this.paginationInfo.itemsPage, this.paginationInfo.actualPage, this.brandSelected, this.typeSelected); - } - - onBrandFilterChanged(event: any, value: number) { - event.preventDefault(); - this.brandSelected = value; - } - - onTypeFilterChanged(event: any, value: number) { - event.preventDefault(); - this.typeSelected = value; - } - - onPageChanged(value: any) { - console.log('catalog pager event fired' + value); - event.preventDefault(); - this.paginationInfo.actualPage = value; - this.getCatalog(this.paginationInfo.itemsPage, value); - } - - addToCart(item: ICatalogItem) { - this.basketService.addItemToBasket(item); - } - - getCatalog(pageSize:number, pageIndex: number, brand?: number, type?: number) { - this.service.getCatalog(pageIndex, pageSize, brand, type).subscribe(catalog => { - this.catalog = catalog; - console.log('catalog items retrieved: ' + catalog.count); - - this.paginationInfo = { - actualPage : catalog.pageIndex, - itemsPage : catalog.pageSize, - totalItems : catalog.count, - totalPages: Math.ceil(catalog.count / catalog.pageSize), - items: catalog.pageSize - }; - - console.log(this.paginationInfo); - }); - } - - getTypes() { - this.service.getTypes().subscribe(types => { - this.types = types; - let alltypes = { id: null, type: 'All' }; - this.types.unshift(alltypes); - console.log('types retrieved: ' + types.length); - }); - } - getBrands() { - this.service.getBrands().subscribe(brands => { - this.brands = brands; - let allBrands = { id: null, brand: 'All' }; - this.brands.unshift(allBrands); - console.log('brands retrieved: ' + brands.length); + getOrders() { + this.service.getOrders().subscribe(orders => { + this.orders = orders; + console.log('orders items retrieved: ' + orders.length); }); } } diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.module.ts b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.module.ts index ef3bec4d7..51f1bb0d9 100644 --- a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.module.ts +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.module.ts @@ -11,4 +11,4 @@ import { Pager } from '../shared/components/pager/pager'; declarations: [OrdersComponent], providers: [OrdersService] }) -export class CatalogModule { } +export class OrdersModule { } diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.service.ts b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.service.ts index ee57cdc86..da1903a11 100644 --- a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.service.ts +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.service.ts @@ -2,9 +2,7 @@ import { Injectable } from '@angular/core'; import { Response } from '@angular/http'; import { DataService } from '../shared/services/data.service'; -import { ICatalog } from '../shared/models/catalog.model'; -import { ICatalogBrand } from '../shared/models/catalogBrand.model'; -import { ICatalogType } from '../shared/models/catalogType.model'; +import { IOrder } from '../shared/models/order.model'; import 'rxjs/Rx'; import { Observable } from 'rxjs/Observable'; @@ -14,35 +12,16 @@ import 'rxjs/add/operator/map'; @Injectable() export class OrdersService { - private catalogUrl: string = 'http://eshopcontainers:5101/api/v1/catalog/items'; - private brandUrl: string = 'http://eshopcontainers:5101/api/v1/catalog/catalogbrands'; - private typesUrl: string = 'http://eshopcontainers:5101/api/v1/catalog/catalogtypes'; + private ordersUrl: string = 'http://eshopcontainers:5102/api/v1/orders'; constructor(private service: DataService) { } - getCatalog(pageIndex: number, pageSize: number, brand: number, type: number): Observable { - var url = this.catalogUrl; - if (brand || type) { - url = this.catalogUrl + '/type/' + ((type) ? type.toString() : 'null') + '/brand/' + ((brand) ? brand.toString() : 'null'); - } - - url = url + '?pageIndex=' + pageIndex + '&pageSize=' + pageSize; + getOrders(): Observable { + var url = this.ordersUrl; return this.service.get(url).map((response: Response) => { return response.json(); }); } - - getBrands(): Observable { - return this.service.get(this.brandUrl).map((response: Response) => { - return response.json(); - }); - } - - getTypes(): Observable { - return this.service.get(this.typesUrl).map((response: Response) => { - return response.json(); - }); - }; -} \ No newline at end of file +} diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/order.model.ts b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/order.model.ts new file mode 100644 index 000000000..35be8bafb --- /dev/null +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/order.model.ts @@ -0,0 +1,6 @@ +export interface IOrder { + ordernumber: number, + date: Date, + status: string, + total: number +} From 89c52fa5fdba2ecbf3614e67abf8fd35d61caea9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Su=C3=A1rez=20Ruiz?= Date: Fri, 23 Dec 2016 13:41:48 +0100 Subject: [PATCH 3/4] Protect from null values (Xamarin Basket) --- .../eShopOnContainers.Core/App.xaml.cs | 2 +- .../ViewModels/CheckoutViewModel.cs | 19 +++++++++++-------- .../eShopOnContainers.Droid.csproj | 2 +- .../eShopOnContainers.TestRunner.Droid.csproj | 2 +- ...opOnContainers.TestRunner.Droid.csproj.bak | 2 +- 5 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/App.xaml.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/App.xaml.cs index 6db54e586..c4aea5cd7 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/App.xaml.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/App.xaml.cs @@ -25,7 +25,7 @@ namespace eShopOnContainers private void InitApp() { - UseMockServices = false; + UseMockServices = true; ViewModelLocator.Instance.UpdateDependencies(UseMockServices); } diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/CheckoutViewModel.cs b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/CheckoutViewModel.cs index 693fbde21..ce26b6d19 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/CheckoutViewModel.cs +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Core/ViewModels/CheckoutViewModel.cs @@ -161,15 +161,18 @@ namespace eShopOnContainers.Core.ViewModels foreach (var basketItem in basketItems) { - orderItems.Add(new OrderItem + if (!string.IsNullOrEmpty(basketItem.ProductName)) { - OrderId = null, - ProductId = basketItem.ProductId, - ProductName = basketItem.ProductName, - PictureUrl = basketItem.PictureUrl, - Quantity = basketItem.Quantity, - UnitPrice = basketItem.UnitPrice - }); + orderItems.Add(new OrderItem + { + OrderId = null, + ProductId = basketItem.ProductId, + ProductName = basketItem.ProductName, + PictureUrl = basketItem.PictureUrl, + Quantity = basketItem.Quantity, + UnitPrice = basketItem.UnitPrice + }); + } } return orderItems; diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.Droid/eShopOnContainers.Droid.csproj b/src/Mobile/eShopOnContainers/eShopOnContainers.Droid/eShopOnContainers.Droid.csproj index 5e83a91c3..8a3b32690 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.Droid/eShopOnContainers.Droid.csproj +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.Droid/eShopOnContainers.Droid.csproj @@ -17,7 +17,7 @@ Off Properties\AndroidManifest.xml true - v6.0 + v7.0 armeabi,armeabi-v7a,x86 diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.Droid/eShopOnContainers.TestRunner.Droid.csproj b/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.Droid/eShopOnContainers.TestRunner.Droid.csproj index c9cb8a265..ffa9c0b55 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.Droid/eShopOnContainers.TestRunner.Droid.csproj +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.Droid/eShopOnContainers.TestRunner.Droid.csproj @@ -16,7 +16,7 @@ Resources\Resource.Designer.cs Off True - v6.0 + v7.0 Properties\AndroidManifest.xml diff --git a/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.Droid/eShopOnContainers.TestRunner.Droid.csproj.bak b/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.Droid/eShopOnContainers.TestRunner.Droid.csproj.bak index ffa9c0b55..c9cb8a265 100644 --- a/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.Droid/eShopOnContainers.TestRunner.Droid.csproj.bak +++ b/src/Mobile/eShopOnContainers/eShopOnContainers.TestRunner.Droid/eShopOnContainers.TestRunner.Droid.csproj.bak @@ -16,7 +16,7 @@ Resources\Resource.Designer.cs Off True - v7.0 + v6.0 Properties\AndroidManifest.xml From ee3241e2fbd29a2dcbc15b9574f912b6baef1614 Mon Sep 17 00:00:00 2001 From: Quique Fernandez Date: Fri, 23 Dec 2016 15:41:08 +0100 Subject: [PATCH 4/4] add orders detail --- .../Client/modules/app.routes.ts | 4 +- .../orders-detail.component.html | 59 +++++++++++++ .../orders-detail.component.scss | 86 +++++++++++++++++++ .../orders-detail/orders-detail.component.ts | 31 +++++++ .../modules/orders/orders.component.html | 2 +- .../Client/modules/orders/orders.component.ts | 2 +- .../Client/modules/orders/orders.module.ts | 3 +- .../Client/modules/orders/orders.service.ts | 12 ++- .../shared/models/catalogItem.model.ts | 1 + .../modules/shared/models/order.model.ts | 15 +++- .../modules/shared/models/orderItem.model.ts | 6 ++ 11 files changed, 211 insertions(+), 10 deletions(-) create mode 100644 src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders-detail/orders-detail.component.html create mode 100644 src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders-detail/orders-detail.component.scss create mode 100644 src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders-detail/orders-detail.component.ts create mode 100644 src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/orderItem.model.ts diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/app.routes.ts b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/app.routes.ts index 3ab758b3f..853b64ac4 100644 --- a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/app.routes.ts +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/app.routes.ts @@ -3,12 +3,14 @@ import { Routes, RouterModule } from '@angular/router'; import { BasketComponent } from './basket/basket.component'; import { CatalogComponent } from './catalog/catalog.component'; import { OrdersComponent } from './orders/orders.component'; +import { OrdersDetailComponent } from './orders/orders-detail/orders-detail.component'; export const routes: Routes = [ { path: '', redirectTo: 'catalog', pathMatch: 'full' }, { path: 'basket', component: BasketComponent }, { path: 'catalog', component: CatalogComponent }, - { path: 'orders', component: OrdersComponent } + { path: 'orders', component: OrdersComponent }, + { path: 'orders/:id', component: OrdersDetailComponent }, //Lazy async modules (angular-loader-router) and enable a router in each module. //{ // path: 'basket', loadChildren: '/basket/basket.module' }); diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders-detail/orders-detail.component.html b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders-detail/orders-detail.component.html new file mode 100644 index 000000000..a6bd0c41b --- /dev/null +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders-detail/orders-detail.component.html @@ -0,0 +1,59 @@ +
+
    +
  • Back to list
  • +
+
+
+
+
+ ORDER NUMBER
+ {{order.ordernumber}} +
+
+ DATE
+ {{order.date | date:'short'}} +
+
+ TOTAL
+ $ {{order.total}} +
+
+ STATUS
+ {{order.status}} +
+
+
+
+ SHIPING ADDRESS
+ {{order.street}}
+ {{order.city}}
+ {{order.country}}
+
+
+
+
ORDER DETAILS
+
+
- PRODUCT + + ORDER NUMBER - + DATE - BRAND + TOTAL - PRICE - - QUANTITY - - COST + STATUS
{{item.productName}}ROSLYN$ {{item.unitPrice}} - - $ {{item.unitPrice * item.quantity}}
-
-
TOTAL
- $ {{totalPrice}} -
+
{{order.ordernumber}}{{order.date | date:'short'}}$ {{order.total}}{{order.status}} + Detail
+ + + + + + + + + + +
{{item.productname}}ROSLYN$ {{item.unitprice}}{{item.units}}$ {{item.units * item.unitprice}}
+
+
+
+ +
+
+
+
TOTAL
+
$ 12.00
+
+
+
\ No newline at end of file diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders-detail/orders-detail.component.scss b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders-detail/orders-detail.component.scss new file mode 100644 index 000000000..6ca4d6fbf --- /dev/null +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders-detail/orders-detail.component.scss @@ -0,0 +1,86 @@ +@import '../../_variables.scss'; + +.esh-orders-detail { + min-height: 80vh; + + &-header { + background-color: #00A69C; + height: 63px; + + li { + list-style: none; + display: inline; + opacity: 0.5; + margin-top: 25px; + margin-left: 10px; + float: right; + cursor: pointer; + color: white; + } + + li a { + color: white; + } + + &-back { + float: left !important; + margin-top: 20px !important; + text-transform: uppercase; + } + + li a:hover { + text-decoration: none; + } + } + + &-container { + min-height: 70vh; + padding-top: 40px; + margin-bottom: 30px; + } + + &-container .table tbody tr:first-child td { + border-top: none; + } + + &-container .table tr { + border-bottom: none; + } + + &-section { + margin-top: 50px; + } + + &-container .table { + margin-left: -7px; + } + + &-total { + margin-bottom: 5px; + margin-left: 20px; + text-align: left; + } + + &-total-label { + font-size: 14px; + color: #404040; + margin-top:10px; + } + + &-total-value { + font-size: 28px; + color: #00a69c; + text-align: left; + } + + &-image { + max-width: 210px; + } + + &-column { + max-width: 120px; + padding: 8px; + text-transform: uppercase; + vertical-align: middle!important; + } +} diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders-detail/orders-detail.component.ts b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders-detail/orders-detail.component.ts new file mode 100644 index 000000000..804aaa57e --- /dev/null +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders-detail/orders-detail.component.ts @@ -0,0 +1,31 @@ +import { Component, OnInit } from '@angular/core'; +import { OrdersService } from '../orders.service'; +import { IOrder } from '../../shared/models/order.model'; +import { ActivatedRoute } from '@angular/router'; + +@Component({ + selector: 'esh-orders-detail .esh-orders-detail', + styleUrls: ['./orders-detail.component.scss'], + templateUrl: './orders-detail.component.html' +}) +export class OrdersDetailComponent implements OnInit { + order = {}; // new order + + constructor(private service: OrdersService, private route: ActivatedRoute) { } + + ngOnInit() { + this.route.params.subscribe(params => { + let id = +params['id']; // (+) converts string 'id' to a number + this.getOrder(id); + }); + } + + getOrder(id: number) { + this.service.getOrder(id).subscribe(order => { + this.order = order; + console.log('order retrieved: ' + order.ordernumber); + console.log(this.order); + }); + } +} + diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.component.html b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.component.html index bbda19c23..deb2eb37f 100644 --- a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.component.html +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.component.html @@ -32,7 +32,7 @@ $ {{order.total}} {{order.status}} - Detail + Detail diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.component.ts b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.component.ts index f52509875..8dd3b0485 100644 --- a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.component.ts +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.component.ts @@ -3,7 +3,7 @@ import { OrdersService } from './orders.service'; import { IOrder } from '../shared/models/order.model'; @Component({ - selector: 'esh-orders .orders', + selector: 'esh-orders .esh-orders', styleUrls: ['./orders.component.scss'], templateUrl: './orders.component.html' }) diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.module.ts b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.module.ts index 51f1bb0d9..f3a920f59 100644 --- a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.module.ts +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.module.ts @@ -3,12 +3,13 @@ import { BrowserModule } from '@angular/platform-browser'; import { SharedModule } from '../shared/shared.module'; import { OrdersComponent } from './orders.component'; +import { OrdersDetailComponent } from './orders-detail/orders-detail.component'; import { OrdersService } from './orders.service'; import { Pager } from '../shared/components/pager/pager'; @NgModule({ imports: [BrowserModule, SharedModule], - declarations: [OrdersComponent], + declarations: [OrdersComponent, OrdersDetailComponent], providers: [OrdersService] }) export class OrdersModule { } diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.service.ts b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.service.ts index da1903a11..be1455058 100644 --- a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.service.ts +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/orders/orders.service.ts @@ -17,8 +17,16 @@ export class OrdersService { constructor(private service: DataService) { } - getOrders(): Observable { - var url = this.ordersUrl; + getOrders(): Observable { + let url = this.ordersUrl; + + return this.service.get(url).map((response: Response) => { + return response.json(); + }); + } + + getOrder(id: number): Observable { + let url = `${this.ordersUrl}/${id}`; return this.service.get(url).map((response: Response) => { return response.json(); diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/catalogItem.model.ts b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/catalogItem.model.ts index 521df03a7..bf4c7ea70 100644 --- a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/catalogItem.model.ts +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/catalogItem.model.ts @@ -8,4 +8,5 @@ export interface ICatalogItem { catalogBrand: string; catalogTypeId: number; catalogType: string; + units: number; } diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/order.model.ts b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/order.model.ts index 35be8bafb..8d38c6a0d 100644 --- a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/order.model.ts +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/order.model.ts @@ -1,6 +1,13 @@ +import {IOrderItem} from './orderItem.model'; + export interface IOrder { - ordernumber: number, - date: Date, - status: string, - total: number + ordernumber: number; + date: Date; + status: string; + total: number; + street?: string; + city?: string; + zipcode?: string; + country?: string; + orderitems?: IOrderItem[]; } diff --git a/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/orderItem.model.ts b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/orderItem.model.ts new file mode 100644 index 000000000..8727d8156 --- /dev/null +++ b/src/Web/WebSPA/eShopOnContainers.WebSPA/Client/modules/shared/models/orderItem.model.ts @@ -0,0 +1,6 @@ +export interface IOrderItem { + pictureurl: string; + productname: string; + unitprice: number; + units: number; +}