From 7cdf78794d005786d016fbb12213e27723664a19 Mon Sep 17 00:00:00 2001 From: Charles Showalter Date: Wed, 25 May 2022 16:16:50 -0700 Subject: [PATCH] Started Client Checkout --- client/package-lock.json | 40 +++++++++++++ client/package.json | 1 + client/src/app/account/account.service.ts | 9 +++ client/src/app/app.module.ts | 4 +- client/src/app/basket/basket.component.html | 57 ++----------------- client/src/app/basket/basket.service.ts | 9 ++- .../checkout-address.component.html | 39 +++++++++++++ .../checkout-address.component.scss | 0 .../checkout-address.component.ts | 29 ++++++++++ .../checkout-delivery.component.html | 27 +++++++++ .../checkout-delivery.component.scss | 0 .../checkout-delivery.component.ts | 30 ++++++++++ .../checkout-payments.component.html | 9 +++ .../checkout-payments.component.scss | 0 .../checkout-payments.component.ts | 15 +++++ .../checkout-review.component.html | 11 ++++ .../checkout-review.component.scss | 0 .../checkout-review.component.ts | 15 +++++ .../checkout-success.component.html | 1 + .../checkout-success.component.scss | 0 .../checkout-success.component.ts | 15 +++++ .../src/app/checkout/checkout.component.html | 22 ++++++- client/src/app/checkout/checkout.component.ts | 39 ++++++++++++- client/src/app/checkout/checkout.module.ts | 16 +++++- client/src/app/checkout/checkout.service.ts | 15 ++++- .../app/core/interceptors/jwt.interceptor.ts | 19 +++++++ .../basket-summary.component.html | 52 +++++++++++++++++ .../basket-summary.component.scss | 0 .../basket-summary.component.ts | 35 ++++++++++++ .../components/stepper/stepper.component.html | 15 +++++ .../components/stepper/stepper.component.scss | 0 .../components/stepper/stepper.component.ts | 20 +++++++ .../src/app/shared/models/deliveryMethods.ts | 7 +++ client/src/app/shared/shared.module.ts | 17 +++++- 34 files changed, 506 insertions(+), 62 deletions(-) create mode 100644 client/src/app/checkout/checkout-address/checkout-address.component.html create mode 100644 client/src/app/checkout/checkout-address/checkout-address.component.scss create mode 100644 client/src/app/checkout/checkout-address/checkout-address.component.ts create mode 100644 client/src/app/checkout/checkout-delivery/checkout-delivery.component.html create mode 100644 client/src/app/checkout/checkout-delivery/checkout-delivery.component.scss create mode 100644 client/src/app/checkout/checkout-delivery/checkout-delivery.component.ts create mode 100644 client/src/app/checkout/checkout-payments/checkout-payments.component.html create mode 100644 client/src/app/checkout/checkout-payments/checkout-payments.component.scss create mode 100644 client/src/app/checkout/checkout-payments/checkout-payments.component.ts create mode 100644 client/src/app/checkout/checkout-review/checkout-review.component.html create mode 100644 client/src/app/checkout/checkout-review/checkout-review.component.scss create mode 100644 client/src/app/checkout/checkout-review/checkout-review.component.ts create mode 100644 client/src/app/checkout/checkout-success/checkout-success.component.html create mode 100644 client/src/app/checkout/checkout-success/checkout-success.component.scss create mode 100644 client/src/app/checkout/checkout-success/checkout-success.component.ts create mode 100644 client/src/app/core/interceptors/jwt.interceptor.ts create mode 100644 client/src/app/shared/basket-summary/basket-summary.component.html create mode 100644 client/src/app/shared/basket-summary/basket-summary.component.scss create mode 100644 client/src/app/shared/basket-summary/basket-summary.component.ts create mode 100644 client/src/app/shared/components/stepper/stepper.component.html create mode 100644 client/src/app/shared/components/stepper/stepper.component.scss create mode 100644 client/src/app/shared/components/stepper/stepper.component.ts create mode 100644 client/src/app/shared/models/deliveryMethods.ts diff --git a/client/package-lock.json b/client/package-lock.json index 8d8c809..d5f27f6 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -9,6 +9,7 @@ "version": "0.0.0", "dependencies": { "@angular/animations": "~13.3.0", + "@angular/cdk": "^13.3.7", "@angular/common": "~13.3.0", "@angular/compiler": "~13.3.0", "@angular/core": "~13.3.0", @@ -355,6 +356,28 @@ "@angular/core": "13.3.7" } }, + "node_modules/@angular/cdk": { + "version": "13.3.7", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-13.3.7.tgz", + "integrity": "sha512-HtGqlrt4+ikbpzooF0LT/uMW6fgRJxLRUoOwkTY1oHhfNXhQaE2p8XEUH2qshl28aCIF8r8zrb6jpd4VqC+tyg==", + "dependencies": { + "tslib": "^2.3.0" + }, + "optionalDependencies": { + "parse5": "^5.0.0" + }, + "peerDependencies": { + "@angular/common": "^13.0.0 || ^14.0.0-0", + "@angular/core": "^13.0.0 || ^14.0.0-0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/cdk/node_modules/parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "optional": true + }, "node_modules/@angular/cli": { "version": "13.3.5", "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-13.3.5.tgz", @@ -11988,6 +12011,23 @@ "tslib": "^2.3.0" } }, + "@angular/cdk": { + "version": "13.3.7", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-13.3.7.tgz", + "integrity": "sha512-HtGqlrt4+ikbpzooF0LT/uMW6fgRJxLRUoOwkTY1oHhfNXhQaE2p8XEUH2qshl28aCIF8r8zrb6jpd4VqC+tyg==", + "requires": { + "parse5": "^5.0.0", + "tslib": "^2.3.0" + }, + "dependencies": { + "parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "optional": true + } + } + }, "@angular/cli": { "version": "13.3.5", "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-13.3.5.tgz", diff --git a/client/package.json b/client/package.json index 86cb800..74660df 100644 --- a/client/package.json +++ b/client/package.json @@ -11,6 +11,7 @@ "private": true, "dependencies": { "@angular/animations": "~13.3.0", + "@angular/cdk": "^13.3.7", "@angular/common": "~13.3.0", "@angular/compiler": "~13.3.0", "@angular/core": "~13.3.0", diff --git a/client/src/app/account/account.service.ts b/client/src/app/account/account.service.ts index fb6f06a..eb924f5 100644 --- a/client/src/app/account/account.service.ts +++ b/client/src/app/account/account.service.ts @@ -3,6 +3,7 @@ import { Injectable } from '@angular/core'; import { Router } from '@angular/router'; import { map, of, ReplaySubject } from 'rxjs'; import { environment } from 'src/environments/environment'; +import { IAddress } from '../shared/models/address'; import { IUser } from '../shared/models/user'; @Injectable({ @@ -64,4 +65,12 @@ export class AccountService { checkEmailExists(email: string){ return this.http.get(this.baseUrl + 'account/emailexists?email=' + email); } + + getUserAddress(){ + return this.http.get(this.baseUrl + 'account/address'); + } + + updateUserAddress(address: IAddress){ + return this.http.put(this.baseUrl + 'account/address', address); + } } diff --git a/client/src/app/app.module.ts b/client/src/app/app.module.ts index 89a177d..f8bebfb 100644 --- a/client/src/app/app.module.ts +++ b/client/src/app/app.module.ts @@ -11,6 +11,7 @@ import { HomeModule } from './home/home.module'; import { ErrorInterceptor } from './core/interceptors/error.interceptor'; import { NgxSpinnerModule } from 'ngx-spinner'; import { LoadingInterceptor } from './core/interceptors/loading.interceptor'; +import { JwtInterceptor } from './core/interceptors/jwt.interceptor'; @NgModule({ declarations: [ @@ -27,7 +28,8 @@ import { LoadingInterceptor } from './core/interceptors/loading.interceptor'; ], providers: [ {provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true}, - {provide: HTTP_INTERCEPTORS, useClass: LoadingInterceptor, multi: true} + {provide: HTTP_INTERCEPTORS, useClass: LoadingInterceptor, multi: true}, + {provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true} ], bootstrap: [AppComponent] }) diff --git a/client/src/app/basket/basket.component.html b/client/src/app/basket/basket.component.html index 3eb0fb2..8e96b69 100644 --- a/client/src/app/basket/basket.component.html +++ b/client/src/app/basket/basket.component.html @@ -7,58 +7,11 @@
-
- - - - - - - - - - - - - - - - - - - -
-
Product
-
-
Price
-
-
quantity
-
-
Total
-
-
Remove
-
-
- {{item.productName}} -
-
- {{item.productName}} -
- Type: {{item.type}} -
-
-
{{item.price | currency}} -
- - {{item.quantity}} - -
-
{{item.price * item.quantity | currency}} - - - -
-
+
diff --git a/client/src/app/basket/basket.service.ts b/client/src/app/basket/basket.service.ts index 04b0695..6e0431a 100644 --- a/client/src/app/basket/basket.service.ts +++ b/client/src/app/basket/basket.service.ts @@ -3,6 +3,7 @@ import { Injectable } from '@angular/core'; import { BehaviorSubject, map } from 'rxjs'; import { environment } from 'src/environments/environment'; import { Basket, IBasket, IBasketItem, IBasketTotals } from '../shared/models/baskset'; +import { IDeliveryMethods } from '../shared/models/deliveryMethods'; import { IProduct } from '../shared/models/product'; @Injectable({ @@ -14,9 +15,15 @@ export class BasketService { basket$ = this.basketSource.asObservable(); private basketTotalSource = new BehaviorSubject(null); basketTotal$ = this.basketTotalSource.asObservable(); + shipping = 0; constructor(private http: HttpClient) { } + setShippingPrice(deliveryMethod: IDeliveryMethods){ + this.shipping = deliveryMethod.price; + this.calculateTotals(); + } + getBasket(id: string){ return this.http.get(this.baseUrl + 'basket?id=' + id).pipe( map((basket: IBasket) => { @@ -92,7 +99,7 @@ export class BasketService { private calculateTotals(){ const basket = this.getCurrentBasketValue(); - const shipping = 0; + const shipping = this.shipping; const subtotal = basket.items.reduce((a, b) => (b.price * b.quantity) + a, 0); const total = subtotal + shipping; this.basketTotalSource.next({ diff --git a/client/src/app/checkout/checkout-address/checkout-address.component.html b/client/src/app/checkout/checkout-address/checkout-address.component.html new file mode 100644 index 0000000..b79cb7e --- /dev/null +++ b/client/src/app/checkout/checkout-address/checkout-address.component.html @@ -0,0 +1,39 @@ +
+
+

Shipping Address

+ +
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+ + +
diff --git a/client/src/app/checkout/checkout-address/checkout-address.component.scss b/client/src/app/checkout/checkout-address/checkout-address.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/client/src/app/checkout/checkout-address/checkout-address.component.ts b/client/src/app/checkout/checkout-address/checkout-address.component.ts new file mode 100644 index 0000000..3c719a2 --- /dev/null +++ b/client/src/app/checkout/checkout-address/checkout-address.component.ts @@ -0,0 +1,29 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { FormGroup } from '@angular/forms'; +import { ToastrService } from 'ngx-toastr'; +import { AccountService } from 'src/app/account/account.service'; + +@Component({ + selector: 'app-checkout-address', + templateUrl: './checkout-address.component.html', + styleUrls: ['./checkout-address.component.scss'] +}) +export class CheckoutAddressComponent implements OnInit { + @Input() checkoutForm: FormGroup; + + constructor(private accountService: AccountService, private toaster: ToastrService) { } + + ngOnInit(): void { + } + + saveUserAddress(){ + this.accountService.updateUserAddress(this.checkoutForm.get('addressForm').value).subscribe({ + next: () => { this.toaster.success('Address Saved'); }, + error: (e: any) => { + this.toaster.error(e.message); + }, + complete: () => { console.log('completed'); } + }); + } + +} diff --git a/client/src/app/checkout/checkout-delivery/checkout-delivery.component.html b/client/src/app/checkout/checkout-delivery/checkout-delivery.component.html new file mode 100644 index 0000000..7cff2e4 --- /dev/null +++ b/client/src/app/checkout/checkout-delivery/checkout-delivery.component.html @@ -0,0 +1,27 @@ +
+

Choose your delivery method.

+
+
+ + +
+
+
+
+ + +
diff --git a/client/src/app/checkout/checkout-delivery/checkout-delivery.component.scss b/client/src/app/checkout/checkout-delivery/checkout-delivery.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/client/src/app/checkout/checkout-delivery/checkout-delivery.component.ts b/client/src/app/checkout/checkout-delivery/checkout-delivery.component.ts new file mode 100644 index 0000000..1cfbd25 --- /dev/null +++ b/client/src/app/checkout/checkout-delivery/checkout-delivery.component.ts @@ -0,0 +1,30 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { FormGroup } from '@angular/forms'; +import { BasketService } from 'src/app/basket/basket.service'; +import { IDeliveryMethods } from 'src/app/shared/models/deliveryMethods'; +import { CheckoutService } from '../checkout.service'; + +@Component({ + selector: 'app-checkout-delivery', + templateUrl: './checkout-delivery.component.html', + styleUrls: ['./checkout-delivery.component.scss'] +}) +export class CheckoutDeliveryComponent implements OnInit { +@Input() checkoutForm: FormGroup; +deliveryMethods: IDeliveryMethods[]; + + constructor(private checkoutService: CheckoutService, private basketService: BasketService) { } + + ngOnInit(): void { + this.checkoutService.getDeliveryMethods().subscribe({ + next: (dm: IDeliveryMethods[]) => { this.deliveryMethods = dm; }, + error: (e: any) => { console.log(e); }, + complete: () => { console.log('completed') } + }); + } + + setShippingPrice(deliveryMethod: IDeliveryMethods){ + this.basketService.setShippingPrice(deliveryMethod); + } + +} diff --git a/client/src/app/checkout/checkout-payments/checkout-payments.component.html b/client/src/app/checkout/checkout-payments/checkout-payments.component.html new file mode 100644 index 0000000..e5a3d92 --- /dev/null +++ b/client/src/app/checkout/checkout-payments/checkout-payments.component.html @@ -0,0 +1,9 @@ +

checkout-payments works!

+
+ + +
diff --git a/client/src/app/checkout/checkout-payments/checkout-payments.component.scss b/client/src/app/checkout/checkout-payments/checkout-payments.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/client/src/app/checkout/checkout-payments/checkout-payments.component.ts b/client/src/app/checkout/checkout-payments/checkout-payments.component.ts new file mode 100644 index 0000000..54d8370 --- /dev/null +++ b/client/src/app/checkout/checkout-payments/checkout-payments.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-checkout-payments', + templateUrl: './checkout-payments.component.html', + styleUrls: ['./checkout-payments.component.scss'] +}) +export class CheckoutPaymentsComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/client/src/app/checkout/checkout-review/checkout-review.component.html b/client/src/app/checkout/checkout-review/checkout-review.component.html new file mode 100644 index 0000000..5cf45f4 --- /dev/null +++ b/client/src/app/checkout/checkout-review/checkout-review.component.html @@ -0,0 +1,11 @@ +
+ +
+
+ + +
diff --git a/client/src/app/checkout/checkout-review/checkout-review.component.scss b/client/src/app/checkout/checkout-review/checkout-review.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/client/src/app/checkout/checkout-review/checkout-review.component.ts b/client/src/app/checkout/checkout-review/checkout-review.component.ts new file mode 100644 index 0000000..b6b8457 --- /dev/null +++ b/client/src/app/checkout/checkout-review/checkout-review.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-checkout-review', + templateUrl: './checkout-review.component.html', + styleUrls: ['./checkout-review.component.scss'] +}) +export class CheckoutReviewComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/client/src/app/checkout/checkout-success/checkout-success.component.html b/client/src/app/checkout/checkout-success/checkout-success.component.html new file mode 100644 index 0000000..c858743 --- /dev/null +++ b/client/src/app/checkout/checkout-success/checkout-success.component.html @@ -0,0 +1 @@ +

checkout-success works!

diff --git a/client/src/app/checkout/checkout-success/checkout-success.component.scss b/client/src/app/checkout/checkout-success/checkout-success.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/client/src/app/checkout/checkout-success/checkout-success.component.ts b/client/src/app/checkout/checkout-success/checkout-success.component.ts new file mode 100644 index 0000000..9919583 --- /dev/null +++ b/client/src/app/checkout/checkout-success/checkout-success.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-checkout-success', + templateUrl: './checkout-success.component.html', + styleUrls: ['./checkout-success.component.scss'] +}) +export class CheckoutSuccessComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/client/src/app/checkout/checkout.component.html b/client/src/app/checkout/checkout.component.html index abf724e..d69c2e3 100644 --- a/client/src/app/checkout/checkout.component.html +++ b/client/src/app/checkout/checkout.component.html @@ -1,3 +1,23 @@
-

Only authorized users should be able to see this.

+
+
+ + + + + + + + + + + + + + +
+
+ +
+
diff --git a/client/src/app/checkout/checkout.component.ts b/client/src/app/checkout/checkout.component.ts index b0398d6..7caad51 100644 --- a/client/src/app/checkout/checkout.component.ts +++ b/client/src/app/checkout/checkout.component.ts @@ -1,4 +1,7 @@ import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { AccountService } from '../account/account.service'; +import { IAddress } from '../shared/models/address'; @Component({ selector: 'app-checkout', @@ -6,10 +9,44 @@ import { Component, OnInit } from '@angular/core'; styleUrls: ['./checkout.component.scss'] }) export class CheckoutComponent implements OnInit { + checkoutForm: FormGroup; - constructor() { } + constructor(private fb: FormBuilder, private accountService: AccountService) { } ngOnInit(): void { + this.createCheckoutForm(); + this.getAddressFormValues(); + } + + createCheckoutForm(){ + this.checkoutForm = this.fb.group({ + addressForm: this.fb.group({ + firstName: [null, Validators.required], + lastName: [null, Validators.required], + street: [null, Validators.required], + city: [null, Validators.required], + state: [null, Validators.required], + zipCode: [null, Validators.required] + }), + deliveryForm: this.fb.group({ + deliveryMethod: [null, Validators.required] + }), + paymenForm: this.fb.group({ + nameOnCard: [null, Validators.required] + }) + }); + } + + getAddressFormValues(){ + this.accountService.getUserAddress().subscribe({ + next: (address: any) => { + if(address){ + this.checkoutForm.get('addressForm').patchValue(address); + } + }, + error: (e: any) => { console.log(e) }, + complete: () => { console.log('completed') } + }); } } diff --git a/client/src/app/checkout/checkout.module.ts b/client/src/app/checkout/checkout.module.ts index cacddad..77ba020 100644 --- a/client/src/app/checkout/checkout.module.ts +++ b/client/src/app/checkout/checkout.module.ts @@ -2,16 +2,28 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { CheckoutComponent } from './checkout.component'; import { CheckoutRoutingModule } from './checkout-routing.module'; +import { SharedModule } from '../shared/shared.module'; +import { CheckoutAddressComponent } from './checkout-address/checkout-address.component'; +import { CheckoutDeliveryComponent } from './checkout-delivery/checkout-delivery.component'; +import { CheckoutReviewComponent } from './checkout-review/checkout-review.component'; +import { CheckoutPaymentsComponent } from './checkout-payments/checkout-payments.component'; +import { CheckoutSuccessComponent } from './checkout-success/checkout-success.component'; @NgModule({ declarations: [ - CheckoutComponent + CheckoutComponent, + CheckoutAddressComponent, + CheckoutDeliveryComponent, + CheckoutReviewComponent, + CheckoutPaymentsComponent, + CheckoutSuccessComponent ], imports: [ CommonModule, - CheckoutRoutingModule + CheckoutRoutingModule, + SharedModule ] }) export class CheckoutModule { } diff --git a/client/src/app/checkout/checkout.service.ts b/client/src/app/checkout/checkout.service.ts index d9285b6..bf6c0f6 100644 --- a/client/src/app/checkout/checkout.service.ts +++ b/client/src/app/checkout/checkout.service.ts @@ -1,9 +1,22 @@ +import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; +import { map } from 'rxjs'; +import { environment } from 'src/environments/environment'; +import { IDeliveryMethods } from '../shared/models/deliveryMethods'; @Injectable({ providedIn: 'root' }) export class CheckoutService { + baseUrl = environment.apiUrl; - constructor() { } + constructor(private http: HttpClient) { } + + getDeliveryMethods(){ + return this.http.get(this.baseUrl + 'orders/deliveryMethods').pipe( + map((dm: IDeliveryMethods[]) => { + return dm.sort((a, b) => b.price - a.price); + }) + ); + } } diff --git a/client/src/app/core/interceptors/jwt.interceptor.ts b/client/src/app/core/interceptors/jwt.interceptor.ts new file mode 100644 index 0000000..3c2762d --- /dev/null +++ b/client/src/app/core/interceptors/jwt.interceptor.ts @@ -0,0 +1,19 @@ +import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from "@angular/common/http"; +import { Injectable } from "@angular/core"; +import { Observable } from "rxjs"; + +@Injectable() +export class JwtInterceptor implements HttpInterceptor { + intercept(req: HttpRequest, next: HttpHandler): Observable> { + const token = localStorage.getItem('token'); + if(token) { + req = req.clone({ + setHeaders: { + Authorization: `Bearer ${token}` + } + }); + } + return next.handle(req); + } + +} diff --git a/client/src/app/shared/basket-summary/basket-summary.component.html b/client/src/app/shared/basket-summary/basket-summary.component.html new file mode 100644 index 0000000..710c997 --- /dev/null +++ b/client/src/app/shared/basket-summary/basket-summary.component.html @@ -0,0 +1,52 @@ +
+ + + + + + + + + + + + + + + + + + + +
+
Product
+
+
Price
+
+
quantity
+
+
Total
+
+
Remove
+
+
+ {{item.productName}} +
+
+ {{item.productName}} +
+ Type: {{item.type}} +
+
+
{{item.price | currency}} +
+ + {{item.quantity}} + +
+
{{item.price * item.quantity | currency}} + + + +
+
diff --git a/client/src/app/shared/basket-summary/basket-summary.component.scss b/client/src/app/shared/basket-summary/basket-summary.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/client/src/app/shared/basket-summary/basket-summary.component.ts b/client/src/app/shared/basket-summary/basket-summary.component.ts new file mode 100644 index 0000000..2cc9f6e --- /dev/null +++ b/client/src/app/shared/basket-summary/basket-summary.component.ts @@ -0,0 +1,35 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { Observable } from 'rxjs'; +import { BasketService } from 'src/app/basket/basket.service'; +import { IBasket, IBasketItem } from '../models/baskset'; + +@Component({ + selector: 'app-basket-summary', + templateUrl: './basket-summary.component.html', + styleUrls: ['./basket-summary.component.scss'] +}) +export class BasketSummaryComponent implements OnInit { + basket$: Observable; + @Output() decrement: EventEmitter = new EventEmitter(); + @Output() increment: EventEmitter = new EventEmitter(); + @Output() remove: EventEmitter = new EventEmitter(); + @Input() isBasket = true; + + constructor(private basketService: BasketService) { } + + ngOnInit(): void { + this.basket$ = this.basketService.basket$; + } + + decrementItemQuantity(item: IBasketItem){ + this.decrement.emit(item); + } + + incrementItemQuantity(item: IBasketItem){ + this.increment.emit(item); + } + + removeBasketItem(item: IBasketItem){ + this.remove.emit(item); + } +} diff --git a/client/src/app/shared/components/stepper/stepper.component.html b/client/src/app/shared/components/stepper/stepper.component.html new file mode 100644 index 0000000..0fcf3a8 --- /dev/null +++ b/client/src/app/shared/components/stepper/stepper.component.html @@ -0,0 +1,15 @@ +
+ +
+ +
+
diff --git a/client/src/app/shared/components/stepper/stepper.component.scss b/client/src/app/shared/components/stepper/stepper.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/client/src/app/shared/components/stepper/stepper.component.ts b/client/src/app/shared/components/stepper/stepper.component.ts new file mode 100644 index 0000000..b4da673 --- /dev/null +++ b/client/src/app/shared/components/stepper/stepper.component.ts @@ -0,0 +1,20 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { CdkStepper } from '@angular/cdk/stepper'; + +@Component({ + selector: 'app-stepper', + templateUrl: './stepper.component.html', + styleUrls: ['./stepper.component.scss'], + providers: [{provide: CdkStepper, useExisting: StepperComponent}] +}) +export class StepperComponent extends CdkStepper implements OnInit { + @Input() linearModeSelected: boolean; + + ngOnInit(): void { + this.linear = this.linearModeSelected; + } + + onClick(index: number){ + this.selectedIndex = index; + } +} diff --git a/client/src/app/shared/models/deliveryMethods.ts b/client/src/app/shared/models/deliveryMethods.ts new file mode 100644 index 0000000..c0f0ad8 --- /dev/null +++ b/client/src/app/shared/models/deliveryMethods.ts @@ -0,0 +1,7 @@ +export interface IDeliveryMethods { + id: number; + shortName: string; + deliveryTime: string; + description: string; + price: number; +} diff --git a/client/src/app/shared/shared.module.ts b/client/src/app/shared/shared.module.ts index a0a30c1..be9fda1 100644 --- a/client/src/app/shared/shared.module.ts +++ b/client/src/app/shared/shared.module.ts @@ -8,6 +8,10 @@ import { PagerComponent } from './components/pager/pager.component'; import { OrderTotalsComponent } from './components/order-totals/order-totals.component'; import { BsDropdownModule } from 'ngx-bootstrap/dropdown'; import { TextInputsComponent } from './components/text-inputs/text-inputs.component'; +import { CdkStepperModule } from '@angular/cdk/stepper'; +import { StepperComponent } from './components/stepper/stepper.component'; +import { BasketSummaryComponent } from './basket-summary/basket-summary.component' +import { RouterModule } from '@angular/router'; @NgModule({ @@ -15,14 +19,18 @@ import { TextInputsComponent } from './components/text-inputs/text-inputs.compon PagingHeaderComponent, PagerComponent, OrderTotalsComponent, - TextInputsComponent + TextInputsComponent, + StepperComponent, + BasketSummaryComponent ], imports: [ CommonModule, PaginationModule.forRoot(), CarouselModule.forRoot(), BsDropdownModule.forRoot(), - ReactiveFormsModule + ReactiveFormsModule, + CdkStepperModule, + RouterModule ], exports: [ PaginationModule, @@ -32,7 +40,10 @@ import { TextInputsComponent } from './components/text-inputs/text-inputs.compon OrderTotalsComponent, ReactiveFormsModule, BsDropdownModule, - TextInputsComponent + TextInputsComponent, + CdkStepperModule, + StepperComponent, + BasketSummaryComponent ] }) export class SharedModule { }