diff --git a/src/app/app.config.ts b/src/app/app.config.ts
index c778438..f09bc97 100644
--- a/src/app/app.config.ts
+++ b/src/app/app.config.ts
@@ -1,7 +1,8 @@
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
+import { provideHttpClient } from '@angular/common/http';
export const appConfig: ApplicationConfig = {
- providers: [provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes)]
+ providers: [provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes), provideHttpClient()]
};
diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts
index 6aeb858..5f521ac 100644
--- a/src/app/app.routes.ts
+++ b/src/app/app.routes.ts
@@ -1,6 +1,12 @@
import { Routes } from '@angular/router';
import {ProductListComponent} from './product-list/product-list.component';
+import { ProductDetailsComponent } from './product-details/product-details.component';
+import { CartComponent } from './cart/cart.component';
+import { ShippingComponent } from './shipping/shipping.component';
export const routes: Routes = [
{ path: '', component: ProductListComponent },
+ { path: 'products/:productId', component: ProductDetailsComponent },
+ { path: 'cart', component: CartComponent },
+ { path: 'shipping', component: ShippingComponent },
];
diff --git a/src/app/cart.service.spec.ts b/src/app/cart.service.spec.ts
new file mode 100644
index 0000000..cb4a750
--- /dev/null
+++ b/src/app/cart.service.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { CartService } from './cart.service';
+
+describe('CartService', () => {
+ let service: CartService;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({});
+ service = TestBed.inject(CartService);
+ });
+
+ it('should be created', () => {
+ expect(service).toBeTruthy();
+ });
+});
diff --git a/src/app/cart.service.ts b/src/app/cart.service.ts
new file mode 100644
index 0000000..1ea47f9
--- /dev/null
+++ b/src/app/cart.service.ts
@@ -0,0 +1,30 @@
+import { Injectable } from '@angular/core';
+import { Product } from './products';
+import { HttpClient } from '@angular/common/http';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class CartService {
+ items: Product[] = [];
+ constructor(
+ private http: HttpClient,
+ ) { }
+
+ addToCart(product: Product) {
+ this.items.push(product);
+ }
+
+ getItems() {
+ return this.items;
+ }
+
+ clearCart() {
+ this.items = [];
+ return this.items;
+ }
+
+ getShippingPrices() {
+ return this.http.get<{type: string, price: number}[]>('/assets/shiping.json');
+ }
+}
diff --git a/src/app/cart/cart.component.css b/src/app/cart/cart.component.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/cart/cart.component.html b/src/app/cart/cart.component.html
new file mode 100644
index 0000000..e54f182
--- /dev/null
+++ b/src/app/cart/cart.component.html
@@ -0,0 +1,12 @@
+
Cart
+
+
+ Shipping Prices
+
+
+@for(item of items; track item.id){
+
+ {{ item.name }}
+ {{ item.price | currency }}
+
+}
diff --git a/src/app/cart/cart.component.spec.ts b/src/app/cart/cart.component.spec.ts
new file mode 100644
index 0000000..03dcc4a
--- /dev/null
+++ b/src/app/cart/cart.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { CartComponent } from './cart.component';
+
+describe('CartComponent', () => {
+ let component: CartComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [CartComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(CartComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/cart/cart.component.ts b/src/app/cart/cart.component.ts
new file mode 100644
index 0000000..6968f5b
--- /dev/null
+++ b/src/app/cart/cart.component.ts
@@ -0,0 +1,21 @@
+import { Component } from '@angular/core';
+import { CartService } from '../cart.service';
+import { Product } from '../products';
+import { CurrencyPipe } from '@angular/common';
+
+@Component({
+ selector: 'app-cart',
+ standalone: true,
+ imports: [CurrencyPipe],
+ templateUrl: './cart.component.html',
+ styleUrl: './cart.component.css'
+})
+export class CartComponent {
+ items: Product[] | undefined = undefined;
+
+ constructor(
+ private cartService: CartService,
+ ) {
+ this.items = this.cartService.getItems();
+ }
+}
diff --git a/src/app/product-alerts/product-alerts.component.css b/src/app/product-alerts/product-alerts.component.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/product-alerts/product-alerts.component.html b/src/app/product-alerts/product-alerts.component.html
new file mode 100644
index 0000000..eb1cf5f
--- /dev/null
+++ b/src/app/product-alerts/product-alerts.component.html
@@ -0,0 +1,5 @@
+@if(product && product.price > 700){
+
+
+
+}
diff --git a/src/app/product-alerts/product-alerts.component.spec.ts b/src/app/product-alerts/product-alerts.component.spec.ts
new file mode 100644
index 0000000..6709df8
--- /dev/null
+++ b/src/app/product-alerts/product-alerts.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ProductAlertsComponent } from './product-alerts.component';
+
+describe('ProductAlertsComponent', () => {
+ let component: ProductAlertsComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [ProductAlertsComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(ProductAlertsComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/product-alerts/product-alerts.component.ts b/src/app/product-alerts/product-alerts.component.ts
new file mode 100644
index 0000000..1414203
--- /dev/null
+++ b/src/app/product-alerts/product-alerts.component.ts
@@ -0,0 +1,14 @@
+import { Component, EventEmitter, Input, Output } from '@angular/core';
+import { Product } from '../products';
+
+@Component({
+ selector: 'app-product-alerts',
+ standalone: true,
+ imports: [],
+ templateUrl: './product-alerts.component.html',
+ styleUrl: './product-alerts.component.css'
+})
+export class ProductAlertsComponent {
+ @Input() product: Product | undefined;
+ @Output() notify = new EventEmitter();
+}
diff --git a/src/app/product-details/product-details.component.css b/src/app/product-details/product-details.component.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/product-details/product-details.component.html b/src/app/product-details/product-details.component.html
new file mode 100644
index 0000000..1af8a15
--- /dev/null
+++ b/src/app/product-details/product-details.component.html
@@ -0,0 +1,7 @@
+Product Details
+
+@if(product){
+
{{ product.name }}
+
{{ product.price | currency }}
+
{{ product.description }}
+
}
diff --git a/src/app/product-details/product-details.component.spec.ts b/src/app/product-details/product-details.component.spec.ts
new file mode 100644
index 0000000..bf10c15
--- /dev/null
+++ b/src/app/product-details/product-details.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ProductDetailsComponent } from './product-details.component';
+
+describe('ProductDetailsComponent', () => {
+ let component: ProductDetailsComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [ProductDetailsComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(ProductDetailsComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/product-details/product-details.component.ts b/src/app/product-details/product-details.component.ts
new file mode 100644
index 0000000..2242c67
--- /dev/null
+++ b/src/app/product-details/product-details.component.ts
@@ -0,0 +1,30 @@
+import { Component, OnInit } from '@angular/core';
+import { Product, products } from '../products';
+import { ActivatedRoute } from '@angular/router';
+import { CurrencyPipe, NgIf } from '@angular/common';
+import { CartService } from '../cart.service';
+
+@Component({
+ selector: 'app-product-details',
+ standalone: true,
+ imports: [CurrencyPipe, NgIf],
+ templateUrl: './product-details.component.html',
+ styleUrl: './product-details.component.css'
+})
+export class ProductDetailsComponent implements OnInit {
+ product: Product | undefined;
+
+ constructor(private route: ActivatedRoute, private cartService: CartService) { }
+
+ addToCart(product: Product) {
+ this.cartService.addToCart(product);
+ window.alert('Your product has genn thrown into the cart!');
+ }
+
+ ngOnInit(): void {
+ const routeParams = this.route.snapshot.paramMap;
+ const productIdFromRoute = Number(routeParams.get('productId'));
+
+ this.product = products.find(product => product.id === productIdFromRoute);
+ }
+}
diff --git a/src/app/product-list/product-list.component.html b/src/app/product-list/product-list.component.html
index 1007667..4191bd9 100644
--- a/src/app/product-list/product-list.component.html
+++ b/src/app/product-list/product-list.component.html
@@ -1 +1,21 @@
Products
+
+@for(product of products; track product.id){
+
+
+
+ @if(product.description){
+
Description: {{product.description}}
+ }
+
+
+
+
+
+}
diff --git a/src/app/product-list/product-list.component.ts b/src/app/product-list/product-list.component.ts
index 5bfe608..a765361 100644
--- a/src/app/product-list/product-list.component.ts
+++ b/src/app/product-list/product-list.component.ts
@@ -1,10 +1,12 @@
import { Component } from '@angular/core';
import { products } from '../products';
+import { ProductAlertsComponent } from '../product-alerts/product-alerts.component';
+import { RouterModule } from '@angular/router';
@Component({
selector: 'app-product-list',
standalone: true,
- imports: [],
+ imports: [ProductAlertsComponent, RouterModule],
templateUrl: './product-list.component.html',
styleUrl: './product-list.component.css'
})
@@ -14,4 +16,8 @@ export class ProductListComponent {
share() {
window.alert('The product has been shared!');
}
+
+ onNotify() {
+ window.alert("You will be notified when the product goes on sale");
+ }
}
diff --git a/src/app/shipping/shipping.component.css b/src/app/shipping/shipping.component.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/shipping/shipping.component.html b/src/app/shipping/shipping.component.html
new file mode 100644
index 0000000..6c4d7ff
--- /dev/null
+++ b/src/app/shipping/shipping.component.html
@@ -0,0 +1,8 @@
+Shipping Prices
+
+@for(shipping of shippingCosts | async; track shipping.type) {
+
+ {{ shipping.type }}
+ {{ shipping.price | currency }}
+
+}
diff --git a/src/app/shipping/shipping.component.spec.ts b/src/app/shipping/shipping.component.spec.ts
new file mode 100644
index 0000000..b7d6707
--- /dev/null
+++ b/src/app/shipping/shipping.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ShippingComponent } from './shipping.component';
+
+describe('ShippingComponent', () => {
+ let component: ShippingComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [ShippingComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(ShippingComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/shipping/shipping.component.ts b/src/app/shipping/shipping.component.ts
new file mode 100644
index 0000000..266839b
--- /dev/null
+++ b/src/app/shipping/shipping.component.ts
@@ -0,0 +1,20 @@
+import { Component } from '@angular/core';
+import { CartService } from '../cart.service';
+import { Observable } from 'rxjs';
+import { AsyncPipe, CurrencyPipe } from '@angular/common';
+
+@Component({
+ selector: 'app-shipping',
+ standalone: true,
+ imports: [AsyncPipe, CurrencyPipe],
+ templateUrl: './shipping.component.html',
+ styleUrl: './shipping.component.css'
+})
+export class ShippingComponent {
+ constructor(private cartService: CartService) { }
+ shippingCosts!: Observable<{ type: string, price: number }[]>;
+
+ ngOnInit(): void {
+ this.shippingCosts = this.cartService.getShippingPrices();
+ }
+}
diff --git a/src/app/top-bar/top-bar.component.html b/src/app/top-bar/top-bar.component.html
index 86bbf82..365fb61 100644
--- a/src/app/top-bar/top-bar.component.html
+++ b/src/app/top-bar/top-bar.component.html
@@ -2,4 +2,6 @@
My Store
-shopping_cartCheckout
+
+ shopping_cartCheckout
+