Skip to content

Commit

Permalink
Merge pull request #2 from Popovkov57/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
Popovkov57 authored Sep 27, 2022
2 parents c154e49 + 60459a6 commit 182c261
Show file tree
Hide file tree
Showing 13 changed files with 281 additions and 7 deletions.
6 changes: 2 additions & 4 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import { Component } from '@angular/core';

@Component({
selector: 'app',
template: `<div class="bg-success p-2 text-center text-white">This is SportStore</div>`
template: "<store></store>"
})
export class AppComponent {
title = 'SportStore';
}
export class AppComponent {}
3 changes: 2 additions & 1 deletion src/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { StoreModule } from './store/store.module';

import { AppComponent } from './app.component';

Expand All @@ -8,7 +9,7 @@ import { AppComponent } from './app.component';
AppComponent
],
imports: [
BrowserModule
BrowserModule, StoreModule
],
providers: [],
bootstrap: [AppComponent]
Expand Down
58 changes: 58 additions & 0 deletions src/app/model/cart.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { Injectable } from "@angular/core";
import { Product } from "./product.model";

@Injectable()
export class Cart {

public lines: CartLine[] = [];
public itemCount: number = 0;
public cartPrice: number = 0;

addLine(product: Product, quantity: number) {
let line = this.lines.find(line => line.product.id == product.id);
if (line != undefined) {
line.quantity += quantity;
} else {
this.lines.push(new CartLine(product, quantity));
}
this.recalculate();
}

updateQuantity(product: Product, quantity: number) {
let line = this.lines.find(line => line.product.id == product.id);
if (line != undefined) {
line.quantity = quantity;
}
this.recalculate();
}

removeLine(id: number) {
let index = this.lines.findIndex(line => line.product.id == id);
this.lines.slice(index, 1);
this.recalculate();
}

clear() {
this.lines = [];
this.itemCount = 0;
this.cartPrice = 0;
}

private recalculate() {
this.itemCount = 0;
this.cartPrice = 0;
this.lines.forEach(line => {
this.itemCount += line.quantity;
this.cartPrice += (line.quantity * line.product.price)
})
}

}

export class CartLine {
constructor(public product: Product, public quantity: number) {}

get lineTotal() {
return this.quantity * this.product.price;
}
}
10 changes: 10 additions & 0 deletions src/app/model/model.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { NgModule } from "@angular/core";
import { ProductRepository } from "./product.repository";
import { StaticDataSource } from "./static.datasource";
import { Cart } from "./cart.model";

@NgModule({
providers: [ProductRepository, StaticDataSource, Cart]
})

export class ModelModule {}
8 changes: 8 additions & 0 deletions src/app/model/product.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export class Product {
constructor (
public id?: number,
public name?: string,
public category?: string,
public description?: string,
public price?: number ) {}
}
28 changes: 28 additions & 0 deletions src/app/model/product.repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Injectable } from "@angular/core";
import { Product } from "./product.model";
import { StaticDataSource } from "./static.datasource";

@Injectable()
export class ProductRepository {
private products: Product[] = [];
private categories: string[] = [];

constructor(private dataSource: StaticDataSource) {
dataSource.getProducts().subscribe(data => {
this.products = data;
this.categories = data.map(p => p.category).filter((c, index, array) => array.indexOf(c) == index).sort();
});
}

getProducts(category: string = null): Product[] {
return this.products.filter(p => category == null || category == p.category);
}

getProduct(id: number): Product {
return this.products.find(p => id == p.id);
}

getCategories(): string[] {
return this.categories;
}
}
28 changes: 28 additions & 0 deletions src/app/model/static.datasource.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Injectable } from "@angular/core";
import { Product } from "./product.model";
import { Observable, from } from "rxjs";

@Injectable()
export class StaticDataSource {
private products: Product[] = [
new Product(1, "Product 1", "Category 1", "Product 1 (Category 1)", 100),
new Product(2, "Product 2", "Category 1", "Product 2 (Category 1)", 100),
new Product(3, "Product 3", "Category 1", "Product 3 (Category 1)", 100),
new Product(4, "Product 4", "Category 1", "Product 4 (Category 1)", 100),
new Product(5, "Product 5", "Category 1", "Product 5 (Category 1)", 100),
new Product(6, "Product 6", "Category 2", "Product 6 (Category 2)", 100),
new Product(7, "Product 7", "Category 2", "Product 7 (Category 2)", 100),
new Product(8, "Product 8", "Category 2", "Product 8 (Category 2)", 100),
new Product(9, "Product 9", "Category 2", "Product 9 (Category 2)", 100),
new Product(10, "Product 10", "Category 2", "Product 10 (Category 2)", 100),
new Product(11, "Product 11", "Category 3", "Product 11 (Category 3)", 100),
new Product(12, "Product 12", "Category 3", "Product 12 (Category 3)", 100),
new Product(13, "Product 13", "Category 3", "Product 13 (Category 3)", 100),
new Product(14, "Product 14", "Category 3", "Product 14 (Category 3)", 100),
new Product(15, "Product 15", "Category 3", "Product 15 (Category 3)", 100)
]

getProducts(): Observable<Product[]> {
return from([this.products]);
}
}
15 changes: 15 additions & 0 deletions src/app/store/cartSummary.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<div class="float-end">
<small>
Your cart:
<span *ngIf="cart.itemCount > 0">
{{ cart.itemCount }} item(s)
{{ cart.cartPrice | currency: "USD":"symbol":"2.2-2"}}
</span>
<span *ngIf="cart.itemCount == 0">
(empty)
</span>
</small>
<button class="btn btn-sm bg-dark text-white" [disabled]="cart.itemCount == 0">
<i class="fa fa-shopping-cart"></i>
</button>
</div>
11 changes: 11 additions & 0 deletions src/app/store/cartSummary.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Component } from "@angular/core";
import { Cart } from "../model/cart.model";

@Component({
selector: "cart-summary",
templateUrl: "cartSummary.component.html"
})

export class CartSummaryComponent {
constructor(public cart: Cart) {}
}
52 changes: 52 additions & 0 deletions src/app/store/store.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<div class="container-fluid">
<div class="row">
<div class="col bg-dark text-white">
<a class="navbar-brand">SPORTS STORE</a>
<cart-summary></cart-summary>
</div>
</div>
<div class="row">
<div class="col-3 p-2">
<div class="d-grid gap-2">
<button class="btn btn-block btn-outline-primary" (click)="changeCategory()">
Home
</button>
<button *ngFor="let category of categories" [class.active]="category == selectedCategory" class="btn btn-outline-primary btn-block" (click)="changeCategory(category)">
{{category}}
</button>
</div>
</div>
<div class="col-9 p-2">
<div *ngFor="let product of products" class="card m-1 p-1 bg-light">
<h4>
{{product.name}}
<span class="badge rounded-pill text-bg-primary float-end">
{{ product.price | currency: "USD":"symbol":"2.2-2"}}
</span>
</h4>
<div class="card-text bg-white p-1">
{{product.description}}
<button class="btn btn-success btn-sm float-end" (click)="addProductToCart(product)">
Add to cart
</button>
</div>
</div>
<div class="form-inline float-start mr-1">
<select class="form-control" [value]="productsPerPage" (change)="changePageSize($event.target.value)">
<option value="3">3 per Page</option>
<option value="4">4 per Page</option>
<option value="6">6 per Page</option>
<option value="8">8 per Page</option>
</select>
</div>
<div class="btn-group float-end">
<button *ngFor="let page of pageNumbers"
(click)="changePage(page)"
class="btn btn-outline-primary"
[class.active]="page == selectedPage">
{{page}}
</button>
</div>
</div>
</div>
</div>
49 changes: 49 additions & 0 deletions src/app/store/store.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Component } from "@angular/core";
import { Product } from "../model/product.model";
import { ProductRepository } from "../model/product.repository";
import { Cart } from "../model/cart.model";

@Component({
selector: "store",
templateUrl: "store.component.html"
})

export class StoreComponent {

public selectedCategory: string = null;
public productsPerPage = 4;
public selectedPage = 1;

constructor(private repository: ProductRepository, private cart: Cart) {}

get products(): Product[] {
let pageIndex = (this.selectedPage - 1) * this.productsPerPage;
return this.repository.getProducts(this.selectedCategory).slice(pageIndex, pageIndex + this.productsPerPage);
}

get categories(): string[] {
return this.repository.getCategories();
}

changeCategory(newCategory?: string) {
this.selectedCategory = newCategory;
}

changePage(newPage: number) {
this.selectedPage = newPage;
}

changePageSize(newSize: number) {
this.productsPerPage = newSize;
this.changePage(1);
}

get pageNumbers(): number[] {
return Array(Math.ceil(this.repository.getProducts(this.selectedCategory).length / this.productsPerPage)).fill(0).map((x,i) => i+1);
}

addProductToCart(product: Product) {
this.cart.addLine(product, 1);
}

}
14 changes: 14 additions & 0 deletions src/app/store/store.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { FormsModule } from "@angular/forms";
import { ModelModule } from "../model/model.module";
import { StoreComponent } from "./store.component";
import { CartSummaryComponent } from "./cartSummary.component";

@NgModule({
imports: [ModelModule, BrowserModule, FormsModule],
declarations: [StoreComponent, CartSummaryComponent],
exports: [StoreComponent, CartSummaryComponent]
})

export class StoreModule {}
6 changes: 4 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@
"lib": [
"es2020",
"dom"
]
],
"strictNullChecks": false
},
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
"strictInjectionParameters": true,
"strictInputAccessModifiers": true,
"strictTemplates": true
"strictTemplates": true,
"strictDomEventTypes": false
}
}

0 comments on commit 182c261

Please sign in to comment.