refractoring

This commit is contained in:
Charles Showalter 2022-05-27 14:21:45 -07:00
parent fc73a27524
commit 1bf08737d2
14 changed files with 66 additions and 138 deletions

View File

@ -11,12 +11,19 @@
(decrement)="decrementItemQuantity($event)" (decrement)="decrementItemQuantity($event)"
(increment)="incrementItemQuantity($event)" (increment)="incrementItemQuantity($event)"
(remove)="removeBasketItem($event)" (remove)="removeBasketItem($event)"
[items]="(basket$ | async).items"
></app-basket-summary> ></app-basket-summary>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-6 offset-6"> <div class="col-6 offset-6">
<app-order-totals></app-order-totals> <app-order-totals
*ngIf="(basketTotals$ | async)"
[shippingPrice]="(basketTotals$ | async).shipping"
[subtotal]="(basketTotals$ | async).subtotal"
[total]="(basketTotals$ | async).total"
>
</app-order-totals>
<a routerLink="/checkout" class="btn btn-outline-primary w-100">Checkout</a> <a routerLink="/checkout" class="btn btn-outline-primary w-100">Checkout</a>
</div> </div>
</div> </div>
@ -24,4 +31,3 @@
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,6 +1,6 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { IBasket, IBasketItem } from '../shared/models/baskset'; import { IBasket, IBasketItem, IBasketTotals } from '../shared/models/baskset';
import { BasketService } from './basket.service'; import { BasketService } from './basket.service';
@Component({ @Component({
@ -10,11 +10,13 @@ import { BasketService } from './basket.service';
}) })
export class BasketComponent implements OnInit { export class BasketComponent implements OnInit {
basket$: Observable<IBasket>; basket$: Observable<IBasket>;
basketTotals$: Observable<IBasketTotals>;
constructor(private basketService: BasketService) { } constructor(private basketService: BasketService) { }
ngOnInit(): void { ngOnInit(): void {
this.basket$ = this.basketService.basket$; this.basket$ = this.basketService.basket$;
this.basketTotals$ = this.basketService.basketTotal$;
} }
removeBasketItem(item: IBasketItem){ removeBasketItem(item: IBasketItem){

View File

@ -1,5 +1,8 @@
<div class="container mt-4"> <div class="container mt-4">
<app-basket-summary [isBasket]=false></app-basket-summary> <app-basket-summary
[isBasket]=false
[items]="(basket$ | async).items"
></app-basket-summary>
</div> </div>
<div class="float-none d-flex justify-content-between flex-column flex-lg-row mb-5"> <div class="float-none d-flex justify-content-between flex-column flex-lg-row mb-5">
<button class="btn btn-outline-primary" cdkStepperPrevious> <button class="btn btn-outline-primary" cdkStepperPrevious>

View File

@ -1,4 +1,7 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { BasketService } from 'src/app/basket/basket.service';
import { IBasket } from 'src/app/shared/models/baskset';
@Component({ @Component({
selector: 'app-checkout-review', selector: 'app-checkout-review',
@ -6,10 +9,12 @@ import { Component, OnInit } from '@angular/core';
styleUrls: ['./checkout-review.component.scss'] styleUrls: ['./checkout-review.component.scss']
}) })
export class CheckoutReviewComponent implements OnInit { export class CheckoutReviewComponent implements OnInit {
basket$: Observable<IBasket>;
constructor() { } constructor(private basketService: BasketService) { }
ngOnInit(): void { ngOnInit(): void {
this.basket$ = this.basketService.basket$;
} }
} }

View File

@ -17,7 +17,12 @@
</app-stepper> </app-stepper>
</div> </div>
<div class="col-3"> <div class="col-3">
<app-order-totals></app-order-totals> <app-order-totals
*ngIf="(basketTotals$ | async)"
[shippingPrice]="(basketTotals$ | async).shipping"
[subtotal]="(basketTotals$ | async).subtotal"
[total]="(basketTotals$ | async).total"
></app-order-totals>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,7 +1,10 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Observable } from 'rxjs';
import { AccountService } from '../account/account.service'; import { AccountService } from '../account/account.service';
import { BasketService } from '../basket/basket.service';
import { IAddress } from '../shared/models/address'; import { IAddress } from '../shared/models/address';
import { IBasketTotals } from '../shared/models/baskset';
@Component({ @Component({
selector: 'app-checkout', selector: 'app-checkout',
@ -9,13 +12,15 @@ import { IAddress } from '../shared/models/address';
styleUrls: ['./checkout.component.scss'] styleUrls: ['./checkout.component.scss']
}) })
export class CheckoutComponent implements OnInit { export class CheckoutComponent implements OnInit {
basketTotals$: Observable<IBasketTotals>;
checkoutForm: FormGroup; checkoutForm: FormGroup;
constructor(private fb: FormBuilder, private accountService: AccountService) { } constructor(private fb: FormBuilder, private accountService: AccountService, private basketService: BasketService) { }
ngOnInit(): void { ngOnInit(): void {
this.createCheckoutForm(); this.createCheckoutForm();
this.getAddressFormValues(); this.getAddressFormValues();
this.basketTotals$ = this.basketService.basketTotal$;
} }
createCheckoutForm(){ createCheckoutForm(){

View File

@ -1,66 +1,18 @@
<div class="container mt-5"> <div class="container mt-5">
<div class="row" *ngIf="order"> <div class="row" *ngIf="order">
<div class="col-8"> <div class="col-8">
<div> <app-basket-summary
<div class="table-responsive"> [items]="order.orderItems"
<table class="table table-striped table-hover table-light"> [isBasket]="false"
<thead> [isOrder]="true"
<tr> ></app-basket-summary>
<th scope="col">
<div class="p-2 px-3 text-uppercase">Product</div>
</th>
<th class="text-center" scope="col">
<div class="p-2 px-3 text-uppercase">Price</div>
</th>
<th class="text-center" scope="col">
<div class="p-2 px-3 text-uppercase">quantity</div>
</th>
<th class="text-center" scope="col">
<div class="p-2 px-3 text-uppercase">Total</div>
</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of order.orderItems">
<th scope="row">
<div class="p-2">
<img class="img-fluid" style="max-height: 50px" src="{{item.pictureUrl}}" alt="{{item.productName}}">
<div class="ms-3 d-inline-block align-middle">
<h5 class="mb-0">
<a class="text-dark">{{item.productName}}</a>
</h5>
</div>
</div>
</th>
<td class="align-middle text-center">{{item.price | currency}}</td>
<td class="align-middle text-center">{{item.quantity}}</td>
<td class="align-middle text-center">{{item.price * item.quantity | currency}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div> </div>
<div class="col-4"> <div class="col-4">
<div class="bg-light px-4 py-3 text-uppercase font-weight-bold"> <app-order-totals
Order Summary [shippingPrice]="order.shippingPrice"
</div> [subtotal]="order.subtotal"
<div class="p-4"> [total]="order.total"
<ul class="list-unstyled mb-4"> ></app-order-totals>
<li class="d-flex justify-content-between py-3 border-bottom">
<strong class="text-muted">Subtotal</strong>
<strong>{{order.subtotal | currency}}</strong>
</li>
<li class="d-flex justify-content-between py-3 border-bottom">
<strong class="text-muted">Shipping and Handling</strong>
<strong>{{order.shippingPrice | currency}}</strong>
</li>
<li class="d-flex justify-content-between py-3 border-bottom">
<strong class="text-muted">Total</strong>
<strong>{{order.total | currency}}</strong>
</li>
</ul>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -3,6 +3,7 @@ import { CommonModule } from '@angular/common';
import { OrderDetailsComponent } from './order-details/order-details.component'; import { OrderDetailsComponent } from './order-details/order-details.component';
import { OrdersComponent } from './orders.component'; import { OrdersComponent } from './orders.component';
import { OrdersRoutingModule } from './orders-routing.module'; import { OrdersRoutingModule } from './orders-routing.module';
import { SharedModule } from '../shared/shared.module';
@ -13,7 +14,8 @@ import { OrdersRoutingModule } from './orders-routing.module';
], ],
imports: [ imports: [
CommonModule, CommonModule,
OrdersRoutingModule OrdersRoutingModule,
SharedModule
] ]
}) })
export class OrdersModule { } export class OrdersModule { }

View File

@ -1,55 +0,0 @@
<ng-container *ngIf="basket$ | async">
<div class="table-responsive">
<table class="table table-striped table-hover table-light">
<thead>
<tr>
<th scope="col">
<div class="p-2 px-3 text-uppercase">Product</div>
</th>
<th class="text-center" scope="col">
<div class="p-2 px-3 text-uppercase">Price</div>
</th>
<th class="text-center" scope="col">
<div class="p-2 px-3 text-uppercase">quantity</div>
</th>
<th class="text-center" scope="col">
<div class="p-2 px-3 text-uppercase">Total</div>
</th>
<th *ngIf="isBasket" class="text-center" scope="col">
<div class="p-2 px-3 text-uppercase">Remove</div>
</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of (basket$ | async).items">
<th scope="row">
<div class="p-2">
<img class="img-fluid" style="max-height: 50px" src="{{item.pictureUrl}}" alt="{{item.productName}}">
<div class="ms-3 d-inline-block align-middle">
<h5 class="mb-0">
<a class="text-dark" routerLink="/shop/{{item.id}}">{{item.productName}}</a>
</h5>
<span class="text-muted font-weight-normal font-italic d-block">Type: {{item.type}}</span>
</div>
</div>
</th>
<td class="align-middle text-center">{{item.price | currency}}</td>
<td class="align-middle text-center">
<div class="d-flex-align-items-center">
<i *ngIf="isBasket" (click)="decrementItemQuantity(item)" class="fa fa-minus-circle text-warning me-2" style="cursor: pointer;"></i>
<span class="font-weight-bold">{{item.quantity}}</span>
<i *ngIf="isBasket" (click)="incrementItemQuantity(item)" class="fa fa-plus-circle text-warning mx-2" style="cursor: pointer;"></i>
</div>
</td>
<td class="align-middle text-center">{{item.price * item.quantity | currency}}</td>
<td *ngIf="isBasket" class="align-middle text-center">
<a class="text-danger" style="cursor: pointer">
<i (click)="removeBasketItem(item)" class="fa fa-trash" style="font-size: 2em"></i>
</a>
</td>
</tr>
</tbody>
</table>
</div>
</ng-container>

View File

@ -1,7 +1,8 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { BasketService } from 'src/app/basket/basket.service'; import { BasketService } from 'src/app/basket/basket.service';
import { IBasket, IBasketItem } from '../models/baskset'; import { IBasket, IBasketItem } from '../../models/baskset';
import { IOrderItem } from '../../models/order';
@Component({ @Component({
selector: 'app-basket-summary', selector: 'app-basket-summary',
@ -9,16 +10,16 @@ import { IBasket, IBasketItem } from '../models/baskset';
styleUrls: ['./basket-summary.component.scss'] styleUrls: ['./basket-summary.component.scss']
}) })
export class BasketSummaryComponent implements OnInit { export class BasketSummaryComponent implements OnInit {
basket$: Observable<IBasket>;
@Output() decrement: EventEmitter<IBasketItem> = new EventEmitter<IBasketItem>(); @Output() decrement: EventEmitter<IBasketItem> = new EventEmitter<IBasketItem>();
@Output() increment: EventEmitter<IBasketItem> = new EventEmitter<IBasketItem>(); @Output() increment: EventEmitter<IBasketItem> = new EventEmitter<IBasketItem>();
@Output() remove: EventEmitter<IBasketItem> = new EventEmitter<IBasketItem>(); @Output() remove: EventEmitter<IBasketItem> = new EventEmitter<IBasketItem>();
@Input() isBasket = true; @Input() isBasket = true;
@Input() items: any = [];
@Input() isOrder = false;
constructor(private basketService: BasketService) { } constructor() { }
ngOnInit(): void { ngOnInit(): void {
this.basket$ = this.basketService.basket$;
} }
decrementItemQuantity(item: IBasketItem){ decrementItemQuantity(item: IBasketItem){

View File

@ -3,18 +3,18 @@
</div> </div>
<div class="p-4"> <div class="p-4">
<p class="font-italic mb-4">Shipping costs will be added during checkout</p> <p class="font-italic mb-4">Shipping costs will be added during checkout</p>
<ul class="list-unstyled mb-4" *ngIf="(basketTotal$ | async) as totals"> <ul class="list-unstyled mb-4">
<li class="d-flex justify-content-between py-3 border-bottom"> <li class="d-flex justify-content-between py-3 border-bottom">
<strong class="text-muted">Subtotal</strong> <strong class="text-muted">Subtotal</strong>
<strong>{{totals.subtotal | currency}}</strong> <strong>{{subtotal | currency}}</strong>
</li> </li>
<li class="d-flex justify-content-between py-3 border-bottom"> <li class="d-flex justify-content-between py-3 border-bottom">
<strong class="text-muted">Shipping and Handling</strong> <strong class="text-muted">Shipping and Handling</strong>
<strong>{{totals.shipping | currency}}</strong> <strong>{{shippingPrice | currency}}</strong>
</li> </li>
<li class="d-flex justify-content-between py-3 border-bottom"> <li class="d-flex justify-content-between py-3 border-bottom">
<strong class="text-muted">Total</strong> <strong class="text-muted">Total</strong>
<strong>{{totals.total | currency}}</strong> <strong>{{total | currency}}</strong>
</li> </li>
</ul> </ul>
</div> </div>

View File

@ -1,4 +1,4 @@
import { Component, OnInit } from '@angular/core'; import { Component, Input, OnInit } from '@angular/core';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { BasketService } from 'src/app/basket/basket.service'; import { BasketService } from 'src/app/basket/basket.service';
import { IBasketTotals } from '../../models/baskset'; import { IBasketTotals } from '../../models/baskset';
@ -9,12 +9,13 @@ import { IBasketTotals } from '../../models/baskset';
styleUrls: ['./order-totals.component.scss'] styleUrls: ['./order-totals.component.scss']
}) })
export class OrderTotalsComponent implements OnInit { export class OrderTotalsComponent implements OnInit {
basketTotal$: Observable<IBasketTotals>; @Input() shippingPrice: number;
@Input() subtotal: number;
@Input() total: number;
constructor(private basketService: BasketService) { } constructor() { }
ngOnInit(): void { ngOnInit(): void {
this.basketTotal$ = this.basketService.basketTotal$;
} }
} }

View File

@ -1,6 +1,6 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { ReactiveFormsModule } from '@angular/forms'; import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { PaginationModule } from 'ngx-bootstrap/pagination'; import { PaginationModule } from 'ngx-bootstrap/pagination';
import { CarouselModule } from 'ngx-bootstrap/carousel'; import { CarouselModule } from 'ngx-bootstrap/carousel';
import { PagingHeaderComponent } from './components/paging-header/paging-header.component'; import { PagingHeaderComponent } from './components/paging-header/paging-header.component';
@ -10,7 +10,7 @@ import { BsDropdownModule } from 'ngx-bootstrap/dropdown';
import { TextInputsComponent } from './components/text-inputs/text-inputs.component'; import { TextInputsComponent } from './components/text-inputs/text-inputs.component';
import { CdkStepperModule } from '@angular/cdk/stepper'; import { CdkStepperModule } from '@angular/cdk/stepper';
import { StepperComponent } from './components/stepper/stepper.component'; import { StepperComponent } from './components/stepper/stepper.component';
import { BasketSummaryComponent } from './basket-summary/basket-summary.component' import { BasketSummaryComponent } from './components/basket-summary/basket-summary.component'
import { RouterModule } from '@angular/router'; import { RouterModule } from '@angular/router';
@ -38,6 +38,7 @@ import { RouterModule } from '@angular/router';
PagerComponent, PagerComponent,
CarouselModule, CarouselModule,
OrderTotalsComponent, OrderTotalsComponent,
FormsModule,
ReactiveFormsModule, ReactiveFormsModule,
BsDropdownModule, BsDropdownModule,
TextInputsComponent, TextInputsComponent,