Skip to content

Instantly share code, notes, and snippets.

@denismaster

denismaster/1.md Secret

Last active July 23, 2019 08:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save denismaster/46d81e6059927cf56c70f3e2b8c772e2 to your computer and use it in GitHub Desktop.
Save denismaster/46d81e6059927cf56c70f3e2b8c772e2 to your computer and use it in GitHub Desktop.
Shareable shopping cart using Angular and Firebase

firebase

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from './home/home.component';
const routes: Routes = [ { path: '', component: HomeComponent, pathMatch: 'full' },];
@NgModule({
imports: [RouterModule.forRoot(routes, {onSameUrlNavigation:'reload' })],
exports: [RouterModule]
})
export class AppRoutingModule { }
import { Component, OnInit } from '@angular/core';
import { ProductCategory } from '../models';
import { Observable } from 'rxjs';
import { take } from 'rxjs/operators'
import { MenuService } from '../menu/menu.service';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
})
export class HomeComponent implements OnInit {
menu$: Observable<ProductCategory[]>;
constructor(private menuService: MenuService) {
}
ngOnInit() {
this.menu$ = this.menuService.getMenu().pipe(take(1));
}
}
<div class="list-group-item list-group-item-action" [class.list-group-item-success]="amount>0" (click)="handleClick()">
<div class="d-flex w-100 justify-content-between">
<div class="mb-1">{{product.name}}</div>
<div *ngIf="product.price">{{product.price}} ₽</div>
</div>
<p class="mb-1 font-weight-light" *ngIf="product.additionalInformation">
{{product.additionalInformation}}</p>
<div *ngIf="amount>0">
<div class="input-group input-group-sm mb-3">
<div class="input-group-prepend" id="button-addon3">
<button class="btn btn-success" (click)="increaseAmount()">+</button>
</div>
<input type="text" disabled class="form-control" placeholder="" [(ngModel)]="amount">
<div class="input-group-append" id="button-addon4">
<button class="btn btn-danger" (click)="decreaseAmount()">-</button>
</div>
</div>
</div>
<small>{{product.weight}}</small>
</div>
<div class="card" *ngIf="category">
<div class="card-body">
<h5 class="card-title">{{category.name}}</h5>
</div>
<div class="list-group">
<app-menu-category-item [product]="product"
*ngFor="let product of category.products"></app-menu-category-item>
</div>
</div>
import { Component, Input } from '@angular/core';
import { ProductCategory } from '../../models';
@Component({
selector: 'app-menu-category',
templateUrl: './menu-category.component.html',
})
export class MenuCategoryComponent {
@Input()
category: ProductCategory = undefined;
}
import { Component, Input, Output, EventEmitter } from '@angular/core';
import { Product, UpdateOrderAction } from '../../models';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-menu-category-item',
templateUrl: './menu-category-item.component.html',
})
export class MenuCategoryItemComponent implements OnInit {
@Input()
product: Product = undefined;
@Output()
click = new EventEmitter<UpdateOrderAction>();
amount: number = 0;
orderId:string;
constructor() {
}
ngOnInit(){
}
handleClick() {
event.stopPropagation();
if (this.amount < 1) {
this.amount = 1;
this.emitAction("add");
}
}
increaseAmount() {
event.stopPropagation();
this.amount = this.amount + 1;
this.emitAction("add");
}
decreaseAmount() {
event.stopPropagation();
this.amount = Math.max(this.amount - 1, 0);
this.emitAction("remove");
}
private emitAction(action: "add" | "remove") {
this.click.emit({
action,
name: this.product.name,
price: this.product.price || 0
});
}
}
<div class="card-columns">
<app-menu-category *ngFor="let category of menu" [category]="category" ></app-menu-category>
</div>
import { Component, Input } from '@angular/core';
import { ProductCategory } from '../models';
@Component({
selector: 'app-menu',
templateUrl: './menu.component.html',
})
export class MenuComponent {
@Input()
menu: ProductCategory[] = []
}
import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import { ProductCategory } from '../models';
@Injectable({ providedIn: 'root' })
export class MenuService {
getMenu(): Observable<ProductCategory[]> {
return of([
{
"name": "First dishes",
"products": [
{
"name": "Chicken soup",
"weight": 300,
"price": 100
},
{
"name": "Borscht",
"weight": "300/110",
"price": 150
},
{
"name": "Mushroom cream soup",
"weight": 300,
"price": 150
},
{
"name": "Okroshka",
"weight": 300,
"price": 120
}
]
},
{
"name": "Sausages",
"products": [
{
"name": "Pig-Beef Sausages",
"weight": 100,
"price": 95
},
{
"name": "Chicken with bacon",
"weight": 100,
"price": 85
},
{
"name": "Sausages with lamb",
"weight": 100,
"price": 95
}
]
},
{
"name": "Salads",
"products": [
{
"name": "Salad with cabbage and sour cream",
"additionalInformation": "Filled with sour cream",
"weight": 200,
"price": 105
},
{
"name": "Vegetable salad",
"additionalInformation": "Filled with vegetable oil",
"weight": 200,
"price": 105
},
{
"name": "Salad with smoked salmon",
"weight": 150,
"price": 160
},
{
"name": "Salad with grilled chicken",
"additionalInformation": "Honey-mustard fill",
"weight": 150,
"price": 140
}
]
},
{
"name": "Side dishes",
"products": [
{
"name": "French fries",
"weight": 120,
"price": 60
},
{
"name": "Tagliatelle",
"weight": 150,
"price": 65
},
{
"name": "Spaghetti",
"weight": 150,
"price": 50
},
{
"name": "Potato pancakes with creamy mushroom sauce",
"weight": 180,
"price": 110
}
]
}
])
}
}
export interface Product {
name: string;
weight?: number | string;
price?: number;
additionalInformation?: string;
}
export interface ProductCategory {
name: string;
products: Product[]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment