Merge branch 'master' of https://labs.xtechnology.org/cshowalter/E-Commerce
This commit is contained in:
commit
3f0a50d2bd
@ -4,16 +4,14 @@ import { NotFoundComponent } from './core/not-found/not-found.component';
|
||||
import { ServerErrorComponent } from './core/server-error/server-error.component';
|
||||
import { TestErrorComponent } from './core/test-error/test-error.component';
|
||||
import { HomeComponent } from './home/home.component';
|
||||
import { ProductDetailsComponent } from './shop/product-details/product-details.component';
|
||||
import { ShopComponent } from './shop/shop.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{path: '', component: HomeComponent},
|
||||
{path: 'test-error', component: TestErrorComponent},
|
||||
{path: 'server-error', component: ServerErrorComponent},
|
||||
{path: 'not-found', component: NotFoundComponent},
|
||||
{path: 'shop', loadChildren: ()=> import('./shop/shop.module').then(mod => mod.ShopModule)},
|
||||
{path: '**', redirectTo: '', pathMatch: 'full'}
|
||||
{path: '', component: HomeComponent, data: {breadcrumb: 'Home'}},
|
||||
{path: 'test-error', component: TestErrorComponent, data: {breadcrumb: 'Test Errors'}},
|
||||
{path: 'server-error', component: ServerErrorComponent, data: {breadcrumb: 'Server Error'}},
|
||||
{path: 'not-found', component: NotFoundComponent, data: {breadcrumb: 'Not Found'}},
|
||||
{path: 'shop', loadChildren: ()=> import('./shop/shop.module').then(mod => mod.ShopModule), data: {breadcrumb: 'Shop'}},
|
||||
{path: '**', redirectTo: 'not-found', pathMatch: 'full'}
|
||||
];
|
||||
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
<app-nav-bar></app-nav-bar>
|
||||
<div class="container" style="margin-top: 140px;">
|
||||
<app-section-header></app-section-header>
|
||||
<div class="container">
|
||||
<router-outlet></router-outlet>
|
||||
</div>
|
||||
|
@ -6,19 +6,25 @@ import { TestErrorComponent } from './test-error/test-error.component';
|
||||
import { NotFoundComponent } from './not-found/not-found.component';
|
||||
import { ServerErrorComponent } from './server-error/server-error.component';
|
||||
import { ToastrModule } from 'ngx-toastr';
|
||||
import { SectionHeaderComponent } from './section-header/section-header.component';
|
||||
import { BreadcrumbModule } from 'xng-breadcrumb';
|
||||
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [NavBarComponent, TestErrorComponent, NotFoundComponent, ServerErrorComponent],
|
||||
declarations: [NavBarComponent, TestErrorComponent, NotFoundComponent, ServerErrorComponent, SectionHeaderComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
RouterModule,
|
||||
BreadcrumbModule,
|
||||
ToastrModule.forRoot({
|
||||
positionClass: 'toast-bottom-right',
|
||||
preventDuplicates: true
|
||||
})
|
||||
],
|
||||
exports: [NavBarComponent]
|
||||
exports: [
|
||||
NavBarComponent,
|
||||
SectionHeaderComponent
|
||||
]
|
||||
})
|
||||
export class CoreModule { }
|
||||
|
@ -6,7 +6,7 @@ import {
|
||||
HttpInterceptor
|
||||
} from '@angular/common/http';
|
||||
import { catchError, Observable, throwError } from 'rxjs';
|
||||
import { Router } from '@angular/router';
|
||||
import { NavigationExtras, Router } from '@angular/router';
|
||||
import { ToastrService } from 'ngx-toastr';
|
||||
|
||||
@Injectable()
|
||||
@ -20,7 +20,12 @@ export class ErrorInterceptor implements HttpInterceptor {
|
||||
if (error){
|
||||
|
||||
if (error.status === 400){
|
||||
this.toastr.error(error.error.message, error.error.statusCode);
|
||||
if (error.error.errors){
|
||||
//log('error thrown ' + error.error);
|
||||
throw error.error;
|
||||
} else {
|
||||
this.toastr.error(error.error.message, error.error.statusCode);
|
||||
}
|
||||
}
|
||||
|
||||
if (error.status === 401){
|
||||
@ -32,7 +37,8 @@ export class ErrorInterceptor implements HttpInterceptor {
|
||||
}
|
||||
|
||||
if (error.status === 500){
|
||||
this.router.navigateByUrl('/server-error');
|
||||
const navigationExtras: NavigationExtras = {state: {error: error.error}};
|
||||
this.router.navigateByUrl('/server-error', navigationExtras);
|
||||
}
|
||||
}
|
||||
return throwError(() => new Error(error));
|
||||
|
@ -0,0 +1,14 @@
|
||||
<ng-container *ngIf="(breadcrumb$ | async) as breadcrumbs">
|
||||
<section *ngIf="breadcrumbs.length > 0 && breadcrumbs[breadcrumbs.length-1].label !== 'Home'" class="py-5" style="margin-top: 105px; background-color:#f5f5f5;">
|
||||
<div class="container">
|
||||
<div class="row d-flex align-item-center">
|
||||
<div class="col-9">
|
||||
<h1>{{breadcrumbs.length > 0 && breadcrumbs[breadcrumbs.length-1].label | titlecase}}</h1>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<xng-breadcrumb></xng-breadcrumb>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</ng-container>
|
@ -0,0 +1,19 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { BreadcrumbService } from 'xng-breadcrumb';
|
||||
|
||||
@Component({
|
||||
selector: 'app-section-header',
|
||||
templateUrl: './section-header.component.html',
|
||||
styleUrls: ['./section-header.component.scss']
|
||||
})
|
||||
export class SectionHeaderComponent implements OnInit {
|
||||
breadcrumb$: Observable<any[]>;
|
||||
|
||||
constructor(private bcService: BreadcrumbService) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.breadcrumb$ = this.bcService.breadcrumbs$;
|
||||
}
|
||||
|
||||
}
|
@ -1,3 +1,17 @@
|
||||
<div class="container mt-5">
|
||||
<h1>Internal Server Error</h1>
|
||||
<h4>Server Internal Error - Refreshing the page clears the exception</h4>
|
||||
<ng-container *ngIf="e">
|
||||
<h5 class="text-danger">{{e.message}}</h5>
|
||||
<p class="font-weight-bold">Note: if you are seeing this, this is not a client side error.</p>
|
||||
<p>What's next?</p>
|
||||
<ol>
|
||||
<li>Open Chrom Dev Tools</li>
|
||||
<li>Inspect the Network Tab</li>
|
||||
<li>Check the failing request</li>
|
||||
<li>Examin the request URL. Is it correct?</li>
|
||||
<li>Reproduce Error in Postman</li>
|
||||
</ol>
|
||||
<p>Following is the stack trace - This is where your investigation begins.</p>
|
||||
<code class="mt-5" style="background-color: whitesmoke;">{{e.details}}</code>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'app-server-error',
|
||||
@ -6,8 +7,12 @@ import { Component, OnInit } from '@angular/core';
|
||||
styleUrls: ['./server-error.component.scss']
|
||||
})
|
||||
export class ServerErrorComponent implements OnInit {
|
||||
e: any;
|
||||
|
||||
constructor() { }
|
||||
constructor(private router: Router) {
|
||||
const navigation = this.router.getCurrentNavigation();
|
||||
this.e = navigation?.extras?.state?.error;
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
@ -3,4 +3,9 @@
|
||||
<button (click)="get404Error()" class="btn btn-outline-primary me-3">Test 404 Error</button>
|
||||
<button (click)="get400Error()" class="btn btn-outline-primary me-3">Test 400 Error</button>
|
||||
<button (click)="get400ValidationError()" class="btn btn-outline-primary me-3">Test 400 Validation Error</button>
|
||||
<div class="row mt-5" *ngIf="validationErrors">
|
||||
<ul class="text-danger">
|
||||
<li *ngFor="let error of validationErrors">{{error}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -9,6 +9,7 @@ import { environment } from 'src/environments/environment';
|
||||
})
|
||||
export class TestErrorComponent implements OnInit {
|
||||
baseURL = environment.apiUrl;
|
||||
validationErrors: any;
|
||||
|
||||
constructor(private http: HttpClient) { }
|
||||
|
||||
@ -49,7 +50,9 @@ export class TestErrorComponent implements OnInit {
|
||||
this.http.get(this.baseURL + 'products/five').subscribe(
|
||||
{
|
||||
next: (response) => { console.log(response); },
|
||||
error: (e: any) => { console.log(e); },
|
||||
error: (e: any) => {
|
||||
//console.log(e.errors);
|
||||
this.validationErrors = e.errors; },
|
||||
complete: () => { console.log('complete'); }
|
||||
}
|
||||
);
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { IProduct } from 'src/app/shared/models/product';
|
||||
import { BreadcrumbService } from 'xng-breadcrumb';
|
||||
import { ShopService } from '../shop.service';
|
||||
|
||||
@Component({
|
||||
@ -11,7 +12,7 @@ import { ShopService } from '../shop.service';
|
||||
export class ProductDetailsComponent implements OnInit {
|
||||
product: IProduct;
|
||||
|
||||
constructor(private shopService: ShopService, private activatedRoute: ActivatedRoute) { }
|
||||
constructor(private shopService: ShopService, private activatedRoute: ActivatedRoute, private bcService: BreadcrumbService) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.loadProduct();
|
||||
@ -20,7 +21,10 @@ export class ProductDetailsComponent implements OnInit {
|
||||
loadProduct(){
|
||||
this.shopService.getProduct(+this.activatedRoute.snapshot.paramMap.get('id')).subscribe(
|
||||
{
|
||||
next: (product) => { this.product = product; },
|
||||
next: (product) => {
|
||||
this.product = product;
|
||||
this.bcService.set('@productDetails', product.name)
|
||||
},
|
||||
error: (e: any) => { console.log(e); },
|
||||
complete: () => { console.log('complete'); }
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
<div class="card h-100 shadow-sm">
|
||||
<img src="{{product.pictureUrl}}" alt="{{product.name}}" class="img-fluid bg-light">
|
||||
<div class="d-flex align-items-center justify-content-center hover-overlay">
|
||||
<button type="button" class="btn btn-sm btn-primary fa fa-shopping-cart me-2"></button>
|
||||
<button routerLink="/shop/{{product.id}}" type="button" class="btn btn-sm btn-primary">View</button>
|
||||
</div>
|
||||
<div class="card-body d-flex flex-column">
|
||||
<a routerLink="/shop/{{product.id}}">
|
||||
<h6 class="text-uppercase">{{product.name}}</h6>
|
||||
</a>
|
||||
<span class="mb-2">{{product.price | currency}}</span>
|
||||
<div class="btn-group mt-auto">
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary fa fa-shopping-cart me-2"></button>
|
||||
<button routerLink="/shop/{{product.id}}" type="button" class="btn btn-sm btn-outline-secondary">View</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -0,0 +1,4 @@
|
||||
.btn {
|
||||
width: 30%;
|
||||
height: 40px;
|
||||
}
|
@ -1,12 +1,11 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { ShopComponent } from './shop.component';
|
||||
import { ProductDetailsComponent } from './product-details/product-details.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{path: '', component: ShopComponent},
|
||||
{path: ':id', component: ProductDetailsComponent},
|
||||
{path: ':id', component: ProductDetailsComponent, data: {breadcrumb: {alias: 'productDetails'}}},
|
||||
]
|
||||
|
||||
@NgModule({
|
||||
|
@ -1,5 +1,5 @@
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="row mt-5">
|
||||
<section class="col-3">
|
||||
<h5 class="text-warning ml-3">Sort</h5>
|
||||
<select class="form-select mb-3" style="width: 100%;" (change)="onSortSelected($event.target.value)">
|
||||
|
@ -5,3 +5,18 @@
|
||||
|
||||
/* Importing Datepicker SCSS file. */
|
||||
@import "node_modules/ngx-bootstrap/datepicker/bs-datepicker";
|
||||
|
||||
.xng-breadcrumb-root {
|
||||
padding: 8px 16px;
|
||||
display: inline;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
label.xng-breadcrumb-trail {
|
||||
margin-bottom: 0;
|
||||
color: orange;
|
||||
}
|
||||
|
||||
xng-breadcrumb-separator {
|
||||
padding: 0 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user