├── .angular-cli.json
├── .editorconfig
├── .gitignore
├── LICENSE
├── README.md
├── docs
├── 0.199027b778401bd939dd.chunk.js
├── 1.aa7a59fc8f79e7c15bbf.chunk.js
├── assets
│ └── bg.jpg
├── bg.e88a2d4544db10e6bdcf.jpg
├── index.html
├── inline.4f04594155dcd0da1dd8.bundle.js
├── main.7b3b5ac7102628da6d15.bundle.js
├── ngsw-manifest.json
├── polyfills.272a0a92e0b8d1d5eab2.bundle.js
├── styles.6a63a43850233e912137.bundle.css
├── sw-register.c12a0e1d4fd37a7ce413.bundle.js
├── vendor.e726a2429f090af1601d.bundle.js
└── worker-basic.min.js
├── e2e
├── app.e2e-spec.ts
├── app.po.ts
└── tsconfig.e2e.json
├── karma.conf.js
├── package-lock.json
├── package.json
├── protractor.conf.js
├── src
├── apfem-theme.scss
├── app
│ ├── app.component.css
│ ├── app.component.html
│ ├── app.component.spec.ts
│ ├── app.component.ts
│ ├── app.module.ts
│ ├── app.routing.ts
│ ├── cart
│ │ ├── cart-item.component.spec.ts
│ │ ├── cart-item.component.ts
│ │ ├── cart-routing.module.ts
│ │ ├── cart.component.html
│ │ ├── cart.component.spec.ts
│ │ ├── cart.component.ts
│ │ ├── cart.module.ts
│ │ ├── cart.service.spec.ts
│ │ ├── cart.service.ts
│ │ ├── cart.ts
│ │ └── index.ts
│ ├── homepage.component.css
│ ├── homepage.component.html
│ ├── homepage.component.ts
│ ├── items
│ │ ├── index.ts
│ │ ├── item-by-category.component.css
│ │ ├── item-by-category.component.html
│ │ ├── item-by-category.component.spec.ts
│ │ ├── item-by-category.component.ts
│ │ ├── item-details.component.css
│ │ ├── item-details.component.html
│ │ ├── item-details.component.spec.ts
│ │ ├── item-details.component.ts
│ │ ├── item-list.component.css
│ │ ├── item-list.component.html
│ │ ├── item-list.component.spec.ts
│ │ ├── item-list.component.ts
│ │ ├── item-routing.module.ts
│ │ ├── item.component.css
│ │ ├── item.component.html
│ │ ├── item.component.spec.ts
│ │ ├── item.component.ts
│ │ ├── item.service.spec.ts
│ │ ├── item.service.ts
│ │ ├── item.ts
│ │ └── items.module.ts
│ ├── layouts
│ │ ├── default-layout.component.css
│ │ ├── default-layout.component.html
│ │ ├── default-layout.component.ts
│ │ ├── index.ts
│ │ ├── simple-layout.component.css
│ │ ├── simple-layout.component.html
│ │ └── simple-layout.component.ts
│ └── shared
│ │ ├── carousel.component.ts
│ │ ├── carousel.module.ts
│ │ ├── cart-counter.component.ts
│ │ ├── footer.component.css
│ │ ├── footer.component.html
│ │ ├── footer.component.ts
│ │ ├── index.ts
│ │ ├── main-nav.component.css
│ │ ├── main-nav.component.html
│ │ ├── main-nav.component.ts
│ │ ├── side-nav.component.css
│ │ ├── side-nav.component.html
│ │ ├── side-nav.component.ts
│ │ └── slide.component.ts
├── assets
│ ├── .gitkeep
│ └── bg.jpg
├── environments
│ ├── environment.prod.ts
│ └── environment.ts
├── fav.png
├── index.html
├── main.ts
├── polyfills.ts
├── styles.css
├── test.ts
├── tsconfig.app.json
├── tsconfig.spec.json
└── typings.d.ts
├── tsconfig.json
└── tslint.json
/.angular-cli.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3 | "project": {
4 | "name": "angular-pwa-firebase-ecommerce"
5 | },
6 | "apps": [
7 | {
8 | "root": "src",
9 | "outDir": "dist",
10 | "assets": [
11 | "assets",
12 | "favicon.ico"
13 | ],
14 | "index": "index.html",
15 | "main": "main.ts",
16 | "polyfills": "polyfills.ts",
17 | "test": "test.ts",
18 | "tsconfig": "tsconfig.app.json",
19 | "testTsconfig": "tsconfig.spec.json",
20 | "prefix": "apfem",
21 | "serviceWorker": true,
22 | "styles": [
23 | "styles.css",
24 | "apfem-theme.scss"
25 | ],
26 | "scripts": [],
27 | "environmentSource": "environments/environment.ts",
28 | "environments": {
29 | "dev": "environments/environment.ts",
30 | "prod": "environments/environment.prod.ts"
31 | }
32 | }
33 | ],
34 | "e2e": {
35 | "protractor": {
36 | "config": "./protractor.conf.js"
37 | }
38 | },
39 | "lint": [
40 | {
41 | "project": "src/tsconfig.app.json"
42 | },
43 | {
44 | "project": "src/tsconfig.spec.json"
45 | },
46 | {
47 | "project": "e2e/tsconfig.e2e.json"
48 | }
49 | ],
50 | "test": {
51 | "karma": {
52 | "config": "./karma.conf.js"
53 | }
54 | },
55 | "defaults": {
56 | "styleExt": "css",
57 | "component": {
58 | }
59 | }
60 | }
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # Editor configuration, see http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.md]
12 | max_line_length = off
13 | trim_trailing_whitespace = false
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # compiled output
4 | /tmp
5 | /out-tsc
6 | /dist
7 | firebase.json
8 | .firebaserc
9 |
10 | # dependencies
11 | /node_modules
12 |
13 | # IDEs and editors
14 | /.idea
15 | .project
16 | .classpath
17 | .c9/
18 | *.launch
19 | .settings/
20 | *.sublime-workspace
21 |
22 | # IDE - VSCode
23 | .vscode/*
24 | !.vscode/settings.json
25 | !.vscode/tasks.json
26 | !.vscode/launch.json
27 | !.vscode/extensions.json
28 | .vscode-upload.json
29 | launch.json
30 |
31 | # misc
32 | /.sass-cache
33 | /connect.lock
34 | /coverage
35 | /libpeerconnection.log
36 | npm-debug.log
37 | testem.log
38 | /typings
39 |
40 | # e2e
41 | /e2e/*.js
42 | /e2e/*.map
43 |
44 | # System Files
45 | .DS_Store
46 | Thumbs.db
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Koko Godswill Davis
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # This is an E-commerce PWA(Progressive Web Application) built with Angular 4, Angular Material and Google Firebase
2 |
3 | Live demo can be found here: (https://apfem-c20fc.firebaseapp.com/)
4 |
5 | # Requirements
6 | - [Angular 4+](https://angular.io)
7 | - [Angular CLI v1.1.0](https://github.com/angular/angular-cli)
8 | - [Angular Material 2](https://github.com/angular/material2)
9 | - [TypeScript 2.4](https://www.typescriptlang.org/)
10 | - [Node v6.6.0](https://nodejs.org/en/blog/release/v6.6.0/)
11 |
12 | # Getting Started
13 |
14 | 1. Clone the [github repository](https://github.com/daviskoko/angular-pwa-firebase-ecommerce.git) to your project directory.
15 | 2. cd to /your-project-directory/angular-pwa-firebase-ecommerce
16 | 3. Run `npm install` to install all the application dependencies
17 | 4. Run `ng serve` to start a development server, open your browser and navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
18 |
19 | To run the development server on a custom development server port(eg: `http://localhost:4201`), run `ng serve --port 4201`
20 |
21 | To customize the application theme to your taste, simply open `apfem-theme.scss` located in the `src` directory and make your changes. For more details on how to them your application, visit [Theming Angular Material](https://material.angular.io/guide/theming)
22 |
23 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
24 |
--------------------------------------------------------------------------------
/docs/0.199027b778401bd939dd.chunk.js:
--------------------------------------------------------------------------------
1 | webpackJsonp([0],{Cs2T:function(l,n,u){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var t=u("3j3K"),e=u("aZMA"),_=u("Nwqk"),i=u("qcWQ"),a=u("TO/P"),o=u("ZWsw"),r=u("2Je8"),d=u("fYnu"),c=u("NVOs"),s=u("Fzro"),m=u("Qbdm"),f=u("5oXY"),g=u("uRPH"),p=u("8vZK"),b=u("QzJe"),v=u("xf8J"),h=u("azVJ");u.d(n,"ItemsModuleNgFactory",function(){return y});var y=t.b(e.a,[],function(l){return t.c([t.d(512,t.e,t.f,[[8,[_.a,i.a,a.a,o.a,o.b,o.c,o.d,o.e]],[3,t.e],t.g]),t.d(4608,r.a,r.b,[t.h]),t.d(4608,d.b,d.b,[]),t.d(5120,d.c,d.d,[[3,d.c],t.q,d.b]),t.d(5120,d.e,d.f,[[3,d.e],d.c]),t.d(4608,d.g,d.g,[d.c,d.e]),t.d(5120,d.h,d.i,[[3,d.h]]),t.d(4608,d.j,d.j,[d.e]),t.d(4608,d.k,d.k,[d.g,d.h,t.e,d.j,t.x,t.v,t.q]),t.d(5120,d.l,d.m,[[3,d.l],t.q,d.b]),t.d(4608,c.a,c.a,[]),t.d(5120,d.n,d.o,[[3,d.n]]),t.d(4608,d.p,d.p,[]),t.d(4608,d.q,d.q,[d.b]),t.d(4608,d.r,d.r,[d.q,d.b,t.q]),t.d(5120,d.s,d.t,[[3,d.s],[2,d.u],d.b]),t.d(4608,d.v,d.v,[d.k,t.v,[2,r.c],[3,d.v]]),t.d(4608,d.w,d.w,[]),t.d(5120,d.x,d.y,[[3,d.x],[2,s.i],m.b]),t.d(4608,m.e,d.a,[]),t.d(4608,d.z,d.z,[d.k,d.s,[3,d.z]]),t.d(4608,c.d,c.d,[]),t.d(512,r.d,r.d,[]),t.d(512,f.w,f.w,[[2,f.m],[2,f.c]]),t.d(512,g.a,g.a,[]),t.d(512,d.A,d.A,[]),t.d(256,d.B,!0,[]),t.d(512,d.C,d.C,[[2,m.d],[2,d.B]]),t.d(512,d.D,d.D,[]),t.d(512,d.E,d.E,[]),t.d(512,d.F,d.F,[]),t.d(512,d.G,d.G,[]),t.d(512,d.H,d.H,[]),t.d(512,d.I,d.I,[]),t.d(512,d.J,d.J,[]),t.d(512,d.K,d.K,[]),t.d(512,d.L,d.L,[]),t.d(512,d.M,d.M,[]),t.d(512,c.b,c.b,[]),t.d(512,c.c,c.c,[]),t.d(512,d.N,d.N,[]),t.d(512,d.O,d.O,[]),t.d(512,d.P,d.P,[]),t.d(512,d.Q,d.Q,[]),t.d(512,d.R,d.R,[]),t.d(512,d.S,d.S,[]),t.d(512,d.T,d.T,[]),t.d(512,d.U,d.U,[]),t.d(512,d.V,d.V,[]),t.d(512,d.W,d.W,[]),t.d(512,d.X,d.X,[]),t.d(512,d.Y,d.Y,[]),t.d(512,d.Z,d.Z,[]),t.d(512,d._0,d._0,[]),t.d(512,d._1,d._1,[]),t.d(512,d._2,d._2,[]),t.d(512,d._3,d._3,[]),t.d(512,d._4,d._4,[]),t.d(512,d._5,d._5,[]),t.d(512,d._6,d._6,[]),t.d(512,d._7,d._7,[]),t.d(512,d._8,d._8,[]),t.d(512,d._9,d._9,[]),t.d(512,d._10,d._10,[]),t.d(512,d._11,d._11,[]),t.d(512,d._12,d._12,[]),t.d(512,d._13,d._13,[]),t.d(512,d._14,d._14,[]),t.d(512,c.e,c.e,[]),t.d(512,p.a,p.a,[]),t.d(512,e.a,e.a,[]),t.d(1024,f.r,function(){return[[{path:"",component:b.a},{path:":slug",component:v.a},{path:":slug/items",component:h.a}]]},[])])})},EfWy:function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=[""]},FaiM:function(l,n,u){"use strict";function t(l){return a._20(0,[(l()(),a._21(0,null,null,46,"md-card",[["class","center-xs item-card mat-card"]],null,null,null,o.p,o.q)),a._22(16384,null,0,r._15,[[2,r._16],a.Q],null,null),a._22(49152,null,0,r._39,[],null,null),(l()(),a._23(0,["\n "])),(l()(),a._21(0,null,0,2,"div",[["class","item-img"]],null,null,null,null,null)),a._22(278528,null,0,d.p,[a.n,a.Q,a.P],{ngStyle:[0,"ngStyle"]},null),a._41(["background","background-repeat","background-size","width","min-height","background-position","color"]),(l()(),a._23(0,["\n "])),(l()(),a._21(0,null,0,27,"md-card-content",[["class","mat-card-content"]],null,null,null,null,null)),a._22(16384,null,0,r._15,[[2,r._16],a.Q],null,null),a._22(16384,null,0,r._98,[],null,null),(l()(),a._23(null,["\n "])),(l()(),a._21(0,null,null,22,"div",[],null,null,null,null,null)),(l()(),a._23(null,["\n "])),(l()(),a._21(0,null,null,19,"md-card-header",[["class","center-xs mat-card-header"]],null,null,null,o.r,o.s)),a._22(16384,null,0,r._15,[[2,r._16],a.Q],null,null),a._22(49152,null,0,r._40,[],null,null),(l()(),a._23(2,["\n "])),(l()(),a._21(0,null,1,14,"md-card-title",[["class","mat-card-title "]],null,null,null,null,null)),a._22(16384,null,0,r._15,[[2,r._16],a.Q],null,null),a._22(16384,null,0,r._99,[],null,null),(l()(),a._23(null,["\n "])),(l()(),a._21(0,null,null,1,"h3",[],null,null,null,null,null)),(l()(),a._23(null,["",""])),(l()(),a._23(null,["\n "])),(l()(),a._21(0,null,null,2,"span",[],null,null,null,null,null)),(l()(),a._23(null,[""," "])),a._43(3),(l()(),a._23(null,["\n "])),(l()(),a._21(0,null,null,2,"small",[["class","old-price"]],null,null,null,null,null)),(l()(),a._23(null,["",""])),a._43(3),(l()(),a._23(null,["\n "])),(l()(),a._23(2,["\n "])),(l()(),a._23(null,["\n "])),(l()(),a._23(null,["\n "])),(l()(),a._23(0,["\n "])),(l()(),a._21(0,null,0,8,"button",[["class","end-xs mat-raised-button"],["color","primary"],["md-raised-button",""]],[[8,"disabled",0]],null,null,o.n,o.o)),a._22(16384,null,0,r._15,[[2,r._16],a.Q],null,null),a._22(180224,null,0,r._35,[a._25,a.Q,r.b,r.l],{color:[0,"color"]},null),a._22(16384,null,0,r._20,[],null,null),(l()(),a._23(0,["Add To Cart "])),(l()(),a._21(0,null,0,3,"md-icon",[["class","mat-icon"],["role","img"]],null,null,null,o.h,o.i)),a._22(16384,null,0,r._15,[[2,r._16],a.Q],null,null),a._22(638976,null,0,r._19,[a._25,a.Q,r.x,[8,null]],null,null),(l()(),a._23(0,["add_shopping_cart"])),(l()(),a._23(0,["\n "]))],function(l,n){l(n,5,0,l(n,6,0,"white url("+n.component.item.photos[0].path+")","no-repeat","cover","auto","250px","center center","#FFF"));l(n,39,0,"primary"),l(n,44,0)},function(l,n){var u=n.component;l(n,23,0,u.item.name),l(n,26,0,a._44(n,26,0,l(n,27,0,a._24(n.parent,0),u.item.price,"USD",!0))),l(n,30,0,a._44(n,30,0,l(n,31,0,a._24(n.parent,0),u.item.old_price,u.USD,!0))),l(n,37,0,a._24(n,39).disabled||null)})}function e(l){return a._20(0,[a._42(0,d.s,[a.h]),(l()(),a._21(0,null,null,6,"a",[],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==a._24(l,2).onClick(u.button,u.ctrlKey,u.metaKey,u.shiftKey)&&t}return t},null,null)),a._22(671744,null,0,c.x,[c.c,c.a,d.e],{routerLink:[0,"routerLink"]},null),a._45(2),(l()(),a._23(null,["\n "])),(l()(),a._26(16777216,null,null,1,null,t)),a._22(16384,null,0,d.k,[a._13,a._14],{ngIf:[0,"ngIf"]},null),(l()(),a._23(null,["\n"])),(l()(),a._23(null,["\n"])),(l()(),a._21(0,null,null,0,"br",[],null,null,null,null,null)),(l()(),a._21(0,null,null,0,"br",[],null,null,null,null,null)),(l()(),a._23(null,["\n"]))],function(l,n){var u=n.component;l(n,2,0,l(n,3,0,"/items",u.selectedItem)),l(n,6,0,u.item)},function(l,n){l(n,1,0,a._24(n,2).target,a._24(n,2).href)})}function _(l){return a._20(0,[(l()(),a._21(0,null,null,1,"apfem-item",[],null,null,null,e,f)),a._22(114688,null,0,s.a,[],null,null)],function(l,n){l(n,1,0)},null)}var i=u("vHjS"),a=u("3j3K"),o=u("ZWsw"),r=u("fYnu"),d=u("2Je8"),c=u("5oXY"),s=u("Jz7b");u.d(n,"b",function(){return f}),n.a=e;var m=[i.a],f=a._19({encapsulation:0,styles:m,data:{}});a._27("apfem-item",s.a,_,{item:"item",selectedItem:"selectedItem"},{},[])},Nwqk:function(l,n,u){"use strict";function t(l){return o._20(0,[(l()(),o._21(0,null,null,2,"apfem-item",[["class","col-xs-12 col-sm-6 col-md-4 col-lg-3"]],null,null,null,r.a,r.b)),o._22(114688,null,0,d.a,[],{item:[0,"item"],selectedItem:[1,"selectedItem"]},null),(l()(),o._23(null,["\n "]))],function(l,n){l(n,1,0,n.context.$implicit,n.context.index)},null)}function e(l){return o._20(0,[(l()(),o._21(0,null,null,4,"div",[["class","row"]],null,null,null,null,null)),(l()(),o._23(null,["\n "])),(l()(),o._26(16777216,null,null,1,null,t)),o._22(802816,null,0,c.j,[o._13,o._14,o.l],{ngForOf:[0,"ngForOf"]},null),(l()(),o._23(null,["\n "]))],function(l,n){l(n,3,0,n.component.items)},null)}function _(l){return o._20(0,[(l()(),o._21(0,null,null,14,"div",[["class","content"]],null,null,null,null,null)),(l()(),o._23(null,["\n "])),(l()(),o._21(0,null,null,11,"div",[["class","col-xs-12 col-sm-12 col-md-12 col-lg-12"]],null,null,null,null,null)),(l()(),o._23(null,["\n "])),(l()(),o._21(0,null,null,0,"br",[],null,null,null,null,null)),(l()(),o._23(null,["\n "])),(l()(),o._21(0,null,null,1,"div",[],null,null,null,null,null)),(l()(),o._23(null,["List of items"])),(l()(),o._23(null,["\n "])),(l()(),o._21(0,null,null,0,"br",[],null,null,null,null,null)),(l()(),o._23(null,["\n "])),(l()(),o._26(16777216,null,null,1,null,e)),o._22(16384,null,0,c.k,[o._13,o._14],{ngIf:[0,"ngIf"]},null),(l()(),o._23(null,["\n "])),(l()(),o._23(null,["\n"]))],function(l,n){l(n,12,0,n.component.items)},null)}function i(l){return o._20(0,[(l()(),o._21(0,null,null,1,"apfem-item-list",[],null,null,null,_,g)),o._22(114688,null,0,s.a,[m.a],null,null)],function(l,n){l(n,1,0)},null)}var a=u("vZf8"),o=u("3j3K"),r=u("FaiM"),d=u("Jz7b"),c=u("2Je8"),s=u("QzJe"),m=u("r1Ir");u.d(n,"a",function(){return p});var f=[a.a],g=o._19({encapsulation:0,styles:f,data:{}}),p=o._27("apfem-item-list",s.a,i,{},{},[])},"TO/P":function(l,n,u){"use strict";function t(l){return i._20(0,[(l()(),i._21(0,null,null,1,"p",[],null,null,null,null,null)),(l()(),i._23(null,["\n item-by-category works!\n"])),(l()(),i._23(null,["\n"]))],null,null)}function e(l){return i._20(0,[(l()(),i._21(0,null,null,1,"apfem-item-by-category",[],null,null,null,t,r)),i._22(114688,null,0,a.a,[],null,null)],function(l,n){l(n,1,0)},null)}var _=u("EfWy"),i=u("3j3K"),a=u("azVJ");u.d(n,"a",function(){return d});var o=[_.a],r=i._19({encapsulation:0,styles:o,data:{}}),d=i._27("apfem-item-by-category",a.a,e,{},{},[])},aZMA:function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=function(){function l(){}return l}()},gqZg:function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=[".img[_ngcontent-%COMP%]{padding:8px;border-radius:4px}"]},qcWQ:function(l,n,u){"use strict";function t(l){return r._20(0,[(l()(),r._21(0,null,null,13,"apfem-slide",[["class","img"]],[[2,"active",null],[2,"item",null],[2,"carousel-item",null]],null,null,d.a,d.b)),r._22(245760,null,0,c.a,[s.a],{active:[0,"active"]},null),(l()(),r._23(0,["\n "])),(l()(),r._21(0,null,0,9,"md-card",[["class","mat-card"]],null,null,null,m.p,m.q)),r._22(16384,null,0,f._15,[[2,f._16],r.Q],null,null),r._22(49152,null,0,f._39,[],null,null),(l()(),r._23(0,["\n "])),(l()(),r._21(0,null,0,4,"div",[["class","mat-card-image"],["md-card-image",""]],null,null,null,null,null)),r._22(278528,null,0,g.p,[r.n,r.Q,r.P],{ngStyle:[0,"ngStyle"]},null),r._41(["background","background-repeat","background-size","width","height","background-position","color"]),r._22(16384,null,0,f._97,[],null,null),(l()(),r._23(null,["\n "])),(l()(),r._23(0,["\n "])),(l()(),r._23(0,["\n "]))],function(l,n){l(n,1,0,n.context.$implicit.active),l(n,8,0,l(n,9,0,"white url("+n.context.$implicit.path+")","no-repeat","cover","auto","60vh","center center","#FFF"))},function(l,n){l(n,0,0,r._24(n,1).active,r._24(n,1).addClass,r._24(n,1).addClass)})}function e(l){return r._20(0,[(l()(),r._21(0,null,null,3,"md-option",[["class","mat-option"],["role","option"]],[[1,"tabindex",0],[2,"mat-selected",null],[2,"mat-option-multiple",null],[2,"mat-active",null],[8,"id",0],[1,"aria-selected",0],[1,"aria-disabled",0],[2,"mat-option-disabled",null]],[[null,"click"],[null,"keydown"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==r._24(l,1)._selectViaInteraction()&&t}if("keydown"===n){t=!1!==r._24(l,1)._handleKeydown(u)&&t}return t},m.j,m.k)),r._22(49152,[[1,4]],0,f._32,[r.Q,[2,f._33],[2,f._16]],{value:[0,"value"]},null),r._22(16384,null,0,f._15,[[2,f._16],r.Q],null,null),(l()(),r._23(0,["\n ","\n "]))],function(l,n){l(n,1,0,n.context.$implicit.value)},function(l,n){l(n,0,0,r._24(n,1)._getTabIndex(),r._24(n,1).selected,r._24(n,1).multiple,r._24(n,1).active,r._24(n,1).id,r._24(n,1).selected.toString(),r._24(n,1).disabled.toString(),r._24(n,1).disabled),l(n,3,0,n.context.$implicit.display)})}function _(l){return r._20(0,[(l()(),r._21(0,null,null,76,"div",[["class","row"]],null,null,null,null,null)),(l()(),r._23(null,["\n "])),(l()(),r._21(0,null,null,8,"div",[["class","col-xs-12 col-sm-7 col-md-7"]],null,null,null,null,null)),(l()(),r._23(null,["\n "])),(l()(),r._21(0,null,null,5,"apfem-carousel",[],null,null,null,p.a,p.b)),r._22(180224,null,0,s.a,[],{noWrap:[0,"noWrap"],interval:[1,"interval"]},null),(l()(),r._23(0,["\n "])),(l()(),r._26(16777216,null,0,1,null,t)),r._22(802816,null,0,g.j,[r._13,r._14,r.l],{ngForOf:[0,"ngForOf"]},null),(l()(),r._23(0,["\n "])),(l()(),r._23(null,["\n "])),(l()(),r._23(null,["\n "])),(l()(),r._21(0,null,null,63,"div",[["class","col-xs-12 col-sm-5 col-md-5"]],null,null,null,null,null)),(l()(),r._23(null,["\n "])),(l()(),r._21(0,null,null,1,"h3",[],null,null,null,null,null)),(l()(),r._23(null,["",""])),(l()(),r._23(null,["\n "])),(l()(),r._21(0,null,null,2,"h4",[],null,null,null,null,null)),(l()(),r._23(null,["",""])),r._43(3),(l()(),r._23(null,["\n "])),(l()(),r._21(0,null,null,3,"p",[],null,null,null,null,null)),(l()(),r._21(0,null,null,2,"small",[["class","old-price"]],null,null,null,null,null)),(l()(),r._23(null,["",""])),r._43(3),(l()(),r._23(null,["\n "])),(l()(),r._21(0,null,null,5,"p",[],null,null,null,null,null)),(l()(),r._21(0,null,null,4,"small",[],null,null,null,null,null)),(l()(),r._23(null,["Availability"])),(l()(),r._21(0,null,null,0,"br",[],null,null,null,null,null)),(l()(),r._21(0,null,null,1,"b",[],null,null,null,null,null)),(l()(),r._23(null,["",""])),(l()(),r._21(0,null,null,0,"br",[],null,null,null,null,null)),(l()(),r._23(null,["\n "])),(l()(),r._21(0,null,null,40,"form",[["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"ngSubmit"],[null,"submit"],[null,"reset"]],function(l,n,u){var t=!0,e=l.component;if("submit"===n){t=!1!==r._24(l,36).onSubmit(u)&&t}if("reset"===n){t=!1!==r._24(l,36).onReset()&&t}if("ngSubmit"===n){t=!1!==e.onAddToCart()&&t}return t},null,null)),r._22(16384,null,0,b.n,[],null,null),r._22(540672,null,0,b.i,[[8,null],[8,null]],{form:[0,"form"]},{ngSubmit:"ngSubmit"}),r._36(2048,null,b.o,null,[b.i]),r._22(16384,null,0,b.p,[b.o],null,null),(l()(),r._23(null,["\n "])),(l()(),r._21(0,null,null,5,"input",[["formControlName","item"],["type","hidden"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"ngModelChange"],[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var t=!0,e=l.component;if("input"===n){t=!1!==r._24(l,41)._handleInput(u.target.value)&&t}if("blur"===n){t=!1!==r._24(l,41).onTouched()&&t}if("compositionstart"===n){t=!1!==r._24(l,41)._compositionStart()&&t}if("compositionend"===n){t=!1!==r._24(l,41)._compositionEnd(u.target.value)&&t}if("ngModelChange"===n){t=!1!==(e.item=u)&&t}return t},null,null)),r._22(16384,null,0,b.q,[r.P,r.Q,[2,b.r]],null,null),r._36(1024,null,b.f,function(l){return[l]},[b.q]),r._22(671744,null,0,b.s,[[3,b.o],[8,null],[8,null],[2,b.f]],{name:[0,"name"],model:[1,"model"]},{update:"ngModelChange"}),r._36(2048,null,b.g,null,[b.s]),r._22(16384,null,0,b.t,[b.g],null,null),(l()(),r._23(null,["\n "])),(l()(),r._21(0,null,null,11,"md-select",[["class","mat-select"],["formControlName","quantity"],["placeholder","Quantity"],["role","listbox"]],[[1,"tabindex",0],[1,"aria-label",0],[1,"aria-labelledby",0],[1,"aria-required",0],[1,"aria-disabled",0],[1,"aria-invalid",0],[1,"aria-owns",0],[2,"mat-select-disabled",null],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"keydown"],[null,"blur"]],function(l,n,u){var t=!0;if("keydown"===n){t=!1!==r._24(l,51)._handleClosedKeydown(u)&&t}if("blur"===n){t=!1!==r._24(l,51)._onBlur()&&t}return t},m.l,m.m)),r._22(16384,null,0,f._15,[[2,f._16],r.Q],null,null),r._22(671744,null,0,b.s,[[3,b.o],[8,null],[8,null],[8,null]],{name:[0,"name"]},null),r._36(2048,null,b.g,null,[b.s]),r._22(1294336,null,2,f._79,[f.e,r._18,r._25,r.Q,[2,f._54],[2,b.g],[8,null],[2,f._66]],{placeholder:[0,"placeholder"]},null),r._35(603979776,1,{options:1}),r._35(603979776,2,{optionGroups:1}),r._22(16384,null,0,b.t,[b.g],null,null),(l()(),r._23(0,["\n "])),(l()(),r._26(16777216,null,0,1,null,e)),r._22(802816,null,0,g.j,[r._13,r._14,r.l],{ngForOf:[0,"ngForOf"]},null),(l()(),r._23(0,["\n "])),(l()(),r._23(null,["\n "])),(l()(),r._21(0,null,null,0,"br",[],null,null,null,null,null)),(l()(),r._21(0,null,null,0,"br",[],null,null,null,null,null)),(l()(),r._23(null,["\n "])),(l()(),r._21(0,null,null,10,"button",[["class","mat-button mat-raised-button"],["color","accent"],["md-button",""],["md-raised-button",""]],[[8,"disabled",0]],null,null,m.n,m.o)),r._22(16384,null,0,f._15,[[2,f._16],r.Q],null,null),r._22(180224,null,0,f._35,[r._25,r.Q,f.b,f.l],{disabled:[0,"disabled"],color:[1,"color"]},null),r._22(16384,null,0,f._18,[],null,null),r._22(16384,null,0,f._20,[],null,null),(l()(),r._23(0,["\n "])),(l()(),r._21(0,null,0,3,"md-icon",[["class","mat-icon"],["role","img"]],null,null,null,m.h,m.i)),r._22(16384,null,0,f._15,[[2,f._16],r.Q],null,null),r._22(638976,null,0,f._19,[r._25,r.Q,f.x,[8,null]],null,null),(l()(),r._23(0,["add_shopping_cart"])),(l()(),r._23(0,[" ADD TO CART\n "])),(l()(),r._23(null,["\n "])),(l()(),r._23(null,["\n "])),(l()(),r._23(null,["\n"]))],function(l,n){var u=n.component;l(n,5,0,u.loop,u.delay),l(n,8,0,u.item.photos),l(n,36,0,u.cartForm);l(n,43,0,"item",u.item);l(n,49,0,"quantity");l(n,51,0,"Quantity"),l(n,57,0,u.numbers);l(n,65,0,!u.cartForm.valid,"accent"),l(n,71,0)},function(l,n){var u=n.component;l(n,15,0,u.item.name),l(n,18,0,r._44(n,18,0,l(n,19,0,r._24(n.parent,0),u.item.price,u.USD,!0))),l(n,23,0,r._44(n,23,0,l(n,24,0,r._24(n.parent,0),u.item.old_price,u.USD,!0))),l(n,31,0,u.item.availability),l(n,34,0,r._24(n,38).ngClassUntouched,r._24(n,38).ngClassTouched,r._24(n,38).ngClassPristine,r._24(n,38).ngClassDirty,r._24(n,38).ngClassValid,r._24(n,38).ngClassInvalid,r._24(n,38).ngClassPending),l(n,40,0,r._24(n,45).ngClassUntouched,r._24(n,45).ngClassTouched,r._24(n,45).ngClassPristine,r._24(n,45).ngClassDirty,r._24(n,45).ngClassValid,r._24(n,45).ngClassInvalid,r._24(n,45).ngClassPending),l(n,47,1,[r._24(n,51).tabIndex,r._24(n,51)._ariaLabel,r._24(n,51).ariaLabelledby,r._24(n,51).required.toString(),r._24(n,51).disabled.toString(),(null==r._24(n,51)._control?null:r._24(n,51)._control.invalid)||"false",r._24(n,51)._optionIds,r._24(n,51).disabled,r._24(n,54).ngClassUntouched,r._24(n,54).ngClassTouched,r._24(n,54).ngClassPristine,r._24(n,54).ngClassDirty,r._24(n,54).ngClassValid,r._24(n,54).ngClassInvalid,r._24(n,54).ngClassPending]),l(n,63,0,r._24(n,65).disabled||null)})}function i(l){return r._20(0,[r._42(0,g.s,[r.h]),(l()(),r._21(0,null,null,0,"br",[],null,null,null,null,null)),(l()(),r._23(null,["\n"])),(l()(),r._21(0,null,null,3,"div",[],null,null,null,null,null)),(l()(),r._21(0,null,null,2,"a",[["routerLink","/items"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==r._24(l,5).onClick(u.button,u.ctrlKey,u.metaKey,u.shiftKey)&&t}return t},null,null)),r._22(671744,null,0,v.x,[v.c,v.a,g.e],{routerLink:[0,"routerLink"]},null),(l()(),r._23(null,["Back to items"])),(l()(),r._23(null,["\n"])),(l()(),r._21(0,null,null,0,"br",[],null,null,null,null,null)),(l()(),r._23(null,["\n"])),(l()(),r._26(16777216,null,null,1,null,_)),r._22(16384,null,0,g.k,[r._13,r._14],{ngIf:[0,"ngIf"]},null),(l()(),r._23(null,["\n"])),(l()(),r._21(0,null,null,11,"div",[["class","row"]],null,null,null,null,null)),(l()(),r._23(null,["\n "])),(l()(),r._21(0,null,null,8,"div",[["class","col-xs-12"]],null,null,null,null,null)),(l()(),r._23(null,["\n "])),(l()(),r._21(0,null,null,0,"br",[],null,null,null,null,null)),(l()(),r._21(0,null,null,2,"small",[],null,null,null,null,null)),(l()(),r._21(0,null,null,1,"b",[],null,null,null,null,null)),(l()(),r._23(null,["Description:"])),(l()(),r._23(null,["\n "])),(l()(),r._21(0,null,null,0,"p",[],[[8,"innerHTML",1]],null,null,null,null)),(l()(),r._23(null,["\n "])),(l()(),r._23(null,["\n"])),(l()(),r._23(null,["\n"])),(l()(),r._21(0,null,null,0,"br",[],null,null,null,null,null))],function(l,n){var u=n.component;l(n,5,0,"/items"),l(n,11,0,u.item)},function(l,n){var u=n.component;l(n,4,0,r._24(n,5).target,r._24(n,5).href),l(n,22,0,r._37(1,"",u.item.description,""))})}function a(l){return r._20(0,[(l()(),r._21(0,null,null,1,"apfem-item-details",[],null,null,null,i,x)),r._22(114688,null,0,h.a,[v.a,y.a,f.z,k.a],null,null)],function(l,n){l(n,1,0)},null)}var o=u("gqZg"),r=u("3j3K"),d=u("7pch"),c=u("BkHY"),s=u("4fdy"),m=u("ZWsw"),f=u("fYnu"),g=u("2Je8"),p=u("4BHv"),b=u("NVOs"),v=u("5oXY"),h=u("xf8J"),y=u("r1Ir"),k=u("L+Ae");u.d(n,"a",function(){return Q});var C=[o.a],x=r._19({encapsulation:0,styles:C,data:{}}),Q=r._27("apfem-item-details",h.a,a,{},{},[])},uRPH:function(l,n,u){"use strict";var t=u("4ppr");u.d(n,"a",function(){return e});var e=(t.b,t.c,t.d,function(){function l(){}return l}())},vHjS:function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=[""]},vZf8:function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=[""]}});
--------------------------------------------------------------------------------
/docs/1.aa7a59fc8f79e7c15bbf.chunk.js:
--------------------------------------------------------------------------------
1 | webpackJsonp([1],{"1ZB8":function(l,n,u){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var t=u("3j3K"),e=u("e4e+"),a=u("4Kkw"),i=u("ZWsw"),_=u("2Je8"),r=u("fYnu"),o=u("NVOs"),d=u("Fzro"),c=u("Qbdm"),s=u("5oXY"),m=u("sUip"),f=u("6Bwb");u.d(n,"CartModuleNgFactory",function(){return g});var g=t.b(e.a,[],function(l){return t.c([t.d(512,t.e,t.f,[[8,[a.a,i.a,i.b,i.c,i.d,i.e]],[3,t.e],t.g]),t.d(4608,_.a,_.b,[t.h]),t.d(4608,r.b,r.b,[]),t.d(5120,r.c,r.d,[[3,r.c],t.q,r.b]),t.d(5120,r.e,r.f,[[3,r.e],r.c]),t.d(4608,r.g,r.g,[r.c,r.e]),t.d(5120,r.h,r.i,[[3,r.h]]),t.d(4608,r.j,r.j,[r.e]),t.d(4608,r.k,r.k,[r.g,r.h,t.e,r.j,t.x,t.v,t.q]),t.d(5120,r.l,r.m,[[3,r.l],t.q,r.b]),t.d(4608,o.a,o.a,[]),t.d(5120,r.n,r.o,[[3,r.n]]),t.d(4608,r.p,r.p,[]),t.d(4608,r.q,r.q,[r.b]),t.d(4608,r.r,r.r,[r.q,r.b,t.q]),t.d(5120,r.s,r.t,[[3,r.s],[2,r.u],r.b]),t.d(4608,r.v,r.v,[r.k,t.v,[2,_.c],[3,r.v]]),t.d(4608,r.w,r.w,[]),t.d(5120,r.x,r.y,[[3,r.x],[2,d.i],c.b]),t.d(4608,c.e,r.a,[]),t.d(4608,r.z,r.z,[r.k,r.s,[3,r.z]]),t.d(4608,o.d,o.d,[]),t.d(512,_.d,_.d,[]),t.d(512,s.w,s.w,[[2,s.m],[2,s.c]]),t.d(512,m.a,m.a,[]),t.d(512,r.A,r.A,[]),t.d(256,r.B,!0,[]),t.d(512,r.C,r.C,[[2,c.d],[2,r.B]]),t.d(512,r.D,r.D,[]),t.d(512,r.E,r.E,[]),t.d(512,r.F,r.F,[]),t.d(512,r.G,r.G,[]),t.d(512,r.H,r.H,[]),t.d(512,r.I,r.I,[]),t.d(512,r.J,r.J,[]),t.d(512,r.K,r.K,[]),t.d(512,r.L,r.L,[]),t.d(512,r.M,r.M,[]),t.d(512,o.b,o.b,[]),t.d(512,o.c,o.c,[]),t.d(512,r.N,r.N,[]),t.d(512,r.O,r.O,[]),t.d(512,r.P,r.P,[]),t.d(512,r.Q,r.Q,[]),t.d(512,r.R,r.R,[]),t.d(512,r.S,r.S,[]),t.d(512,r.T,r.T,[]),t.d(512,r.U,r.U,[]),t.d(512,r.V,r.V,[]),t.d(512,r.W,r.W,[]),t.d(512,r.X,r.X,[]),t.d(512,r.Y,r.Y,[]),t.d(512,r.Z,r.Z,[]),t.d(512,r._0,r._0,[]),t.d(512,r._1,r._1,[]),t.d(512,r._2,r._2,[]),t.d(512,r._3,r._3,[]),t.d(512,r._4,r._4,[]),t.d(512,r._5,r._5,[]),t.d(512,r._6,r._6,[]),t.d(512,r._7,r._7,[]),t.d(512,r._8,r._8,[]),t.d(512,r._9,r._9,[]),t.d(512,r._10,r._10,[]),t.d(512,r._11,r._11,[]),t.d(512,r._12,r._12,[]),t.d(512,r._13,r._13,[]),t.d(512,r._14,r._14,[]),t.d(512,o.e,o.e,[]),t.d(512,e.a,e.a,[]),t.d(1024,s.r,function(){return[[{path:"",component:f.a}]]},[])])})},"3fiE":function(l,n,u){"use strict";var t=u("NVOs");u.d(n,"a",function(){return e});var e=function(){function l(){this.numbers=[{value:1,display:"One"},{value:2,display:"Two"},{value:3,display:"Three"},{value:4,display:"Four"},{value:5,display:"Five"}],this.updateCartForm=new t.l({item:new t.m("",t.k.required),quantity:new t.m("",t.k.required)})}return l.prototype.onUpdateCart=function(){console.log(this.updateCartForm.value)},l.prototype.ngOnInit=function(){},l.ctorParameters=function(){return[]},l}()},"4Kkw":function(l,n,u){"use strict";function t(l){return o._20(0,[(l()(),o._21(0,null,null,2,"apfem-cart-item",[["class","cart-wrapper"]],null,null,null,d.a,d.b)),o._22(114688,null,0,c.a,[],{cartItem:[0,"cartItem"]},null),(l()(),o._23(null,["\n "]))],function(l,n){l(n,1,0,n.context.$implicit)},null)}function e(l){return o._20(0,[(l()(),o._21(0,null,null,31,"div",[["class","row center-xs"]],null,null,null,null,null)),(l()(),o._23(null,["\n "])),(l()(),o._21(0,null,null,12,"div",[["class","col-xs-12 col-sm-6"]],null,null,null,null,null)),(l()(),o._23(null,["\n "])),(l()(),o._21(0,null,null,9,"a",[["class","mat-button"],["color","accent"],["md-button",""],["routerLink","/items"]],[[1,"target",0],[8,"href",4],[1,"disabled",0],[1,"aria-disabled",0],[8,"tabIndex",0]],[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==o._24(l,5).onClick(u.button,u.ctrlKey,u.metaKey,u.shiftKey)&&t}if("click"===n){t=!1!==o._24(l,7)._haltDisabledEvents(u)&&t}return t},s.f,s.g)),o._22(671744,null,0,m.x,[m.c,m.a,f.e],{routerLink:[0,"routerLink"]},null),o._22(16384,null,0,g._15,[[2,g._16],o.Q],null,null),o._22(180224,null,0,g._17,[g.b,g.l,o.Q,o._25],{color:[0,"color"]},null),o._22(16384,null,0,g._18,[],null,null),(l()(),o._21(0,null,0,3,"md-icon",[["class","mat-icon"],["role","img"]],null,null,null,s.h,s.i)),o._22(16384,null,0,g._15,[[2,g._16],o.Q],null,null),o._22(638976,null,0,g._19,[o._25,o.Q,g.x,[8,null]],null,null),(l()(),o._23(0,["keyboard_arrow_left"])),(l()(),o._23(0,[" CONTINUE SHOPPING"])),(l()(),o._23(null,["\n "])),(l()(),o._21(0,null,null,0,"br",[],null,null,null,null,null)),(l()(),o._21(0,null,null,0,"br",[],null,null,null,null,null)),(l()(),o._21(0,null,null,0,"br",[],null,null,null,null,null)),(l()(),o._23(null,["\n "])),(l()(),o._21(0,null,null,11,"div",[["class","col-xs-12 col-sm-6"]],null,null,null,null,null)),(l()(),o._23(null,["\n "])),(l()(),o._21(0,null,null,8,"a",[["class","mat-raised-button"],["color","primary"],["href","javascript:;"],["md-raised-button",""]],[[1,"disabled",0],[1,"aria-disabled",0],[8,"tabIndex",0]],[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==o._24(l,23)._haltDisabledEvents(u)&&t}return t},s.f,s.g)),o._22(16384,null,0,g._15,[[2,g._16],o.Q],null,null),o._22(180224,null,0,g._17,[g.b,g.l,o.Q,o._25],{color:[0,"color"]},null),o._22(16384,null,0,g._20,[],null,null),(l()(),o._23(0,["CHECK OUT"])),(l()(),o._21(0,null,0,3,"md-icon",[["class","mat-icon"],["role","img"]],null,null,null,s.h,s.i)),o._22(16384,null,0,g._15,[[2,g._16],o.Q],null,null),o._22(638976,null,0,g._19,[o._25,o.Q,g.x,[8,null]],null,null),(l()(),o._23(0,["keyboard_arrow_right"])),(l()(),o._23(null,["\n "])),(l()(),o._23(null,["\n "]))],function(l,n){l(n,5,0,"/items");l(n,7,0,"accent"),l(n,11,0);l(n,23,0,"primary"),l(n,28,0)},function(l,n){l(n,4,0,o._24(n,5).target,o._24(n,5).href,o._24(n,7).disabled||null,o._24(n,7)._isAriaDisabled,o._24(n,7).tabIndex),l(n,21,0,o._24(n,23).disabled||null,o._24(n,23)._isAriaDisabled,o._24(n,23).tabIndex)})}function a(l){return o._20(0,[(l()(),o._21(0,null,null,8,"div",[["class","row center-xs"]],null,null,null,null,null)),(l()(),o._23(null,["\n "])),(l()(),o._21(0,null,null,5,"a",[["class","mat-raised-button"],["color","primary"],["md-raised-button",""],["routerLink","/items"]],[[1,"target",0],[8,"href",4],[1,"disabled",0],[1,"aria-disabled",0],[8,"tabIndex",0]],[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==o._24(l,3).onClick(u.button,u.ctrlKey,u.metaKey,u.shiftKey)&&t}if("click"===n){t=!1!==o._24(l,5)._haltDisabledEvents(u)&&t}return t},s.f,s.g)),o._22(671744,null,0,m.x,[m.c,m.a,f.e],{routerLink:[0,"routerLink"]},null),o._22(16384,null,0,g._15,[[2,g._16],o.Q],null,null),o._22(180224,null,0,g._17,[g.b,g.l,o.Q,o._25],{color:[0,"color"]},null),o._22(16384,null,0,g._20,[],null,null),(l()(),o._23(0,["SHOPPING LIST"])),(l()(),o._23(null,["\n "]))],function(l,n){l(n,3,0,"/items");l(n,5,0,"primary")},function(l,n){l(n,2,0,o._24(n,3).target,o._24(n,3).href,o._24(n,5).disabled||null,o._24(n,5)._isAriaDisabled,o._24(n,5).tabIndex)})}function i(l){return o._20(0,[(l()(),o._21(0,null,null,22,"div",[["class","cart"]],null,null,null,null,null)),(l()(),o._23(null,["\n "])),(l()(),o._21(0,null,null,19,"div",[["class","row center-xs"]],null,null,null,null,null)),(l()(),o._23(null,["\n "])),(l()(),o._21(0,null,null,16,"div",[["class","col-xs-11 col-sm-8 col-md-6"]],null,null,null,null,null)),(l()(),o._23(null,["\n "])),(l()(),o._21(0,null,null,1,"h3",[],null,null,null,null,null)),(l()(),o._23(null,["My Cart"])),(l()(),o._23(null,["\n "])),(l()(),o._21(0,null,null,1,"small",[],null,null,null,null,null)),(l()(),o._23(null,["You have "," items in your basket"])),(l()(),o._23(null,["\n "])),(l()(),o._26(16777216,null,null,1,null,t)),o._22(802816,null,0,f.j,[o._13,o._14,o.l],{ngForOf:[0,"ngForOf"]},null),(l()(),o._23(null,["\n "])),(l()(),o._26(16777216,null,null,1,null,e)),o._22(16384,null,0,f.k,[o._13,o._14],{ngIf:[0,"ngIf"]},null),(l()(),o._23(null,["\n "])),(l()(),o._26(16777216,null,null,1,null,a)),o._22(16384,null,0,f.k,[o._13,o._14],{ngIf:[0,"ngIf"]},null),(l()(),o._23(null,["\n "])),(l()(),o._23(null,["\n "])),(l()(),o._23(null,["\n"]))],function(l,n){var u=n.component;l(n,13,0,u.cart),l(n,16,0,u.cart.length>=1),l(n,19,0,u.cart.length<1)},function(l,n){l(n,10,0,n.component.cart.length)})}function _(l){return o._20(0,[(l()(),o._26(16777216,null,null,1,null,i)),o._22(16384,null,0,f.k,[o._13,o._14],{ngIf:[0,"ngIf"]},null)],function(l,n){l(n,1,0,n.component.cart)},null)}function r(l){return o._20(0,[(l()(),o._21(0,null,null,1,"apfem-cart",[],null,null,null,_,h)),o._22(114688,null,0,b.a,[p.a],null,null)],function(l,n){l(n,1,0)},null)}var o=u("3j3K"),d=u("XsFK"),c=u("3fiE"),s=u("ZWsw"),m=u("5oXY"),f=u("2Je8"),g=u("fYnu"),b=u("6Bwb"),p=u("L+Ae");u.d(n,"a",function(){return y});var v=[".cart[_ngcontent-%COMP%]{min-height:500px;}"],h=o._19({encapsulation:0,styles:v,data:{}}),y=o._27("apfem-cart",b.a,r,{},{},[])},XsFK:function(l,n,u){"use strict";function t(l){return _._20(0,[(l()(),_._21(0,null,null,6,"div",[["class","col-xs-5"]],null,null,null,null,null)),(l()(),_._23(null,["\n "])),(l()(),_._21(0,null,null,3,"div",[["class","item-img"]],null,null,null,null,null)),_._22(278528,null,0,r.p,[_.n,_.Q,_.P],{ngStyle:[0,"ngStyle"]},null),_._41(["background","background-repeat","background-size","width","min-height","background-position","color"]),(l()(),_._23(null,["\n "])),(l()(),_._23(null,["\n "]))],function(l,n){l(n,3,0,l(n,4,0,"white url("+n.component.cartItem.val.item.photos[0].path+")","no-repeat","cover","auto","200px","center center","#FFF"))},null)}function e(l){return _._20(0,[(l()(),_._21(0,null,null,3,"md-option",[["class","mat-option"],["role","option"]],[[1,"tabindex",0],[2,"mat-selected",null],[2,"mat-option-multiple",null],[2,"mat-active",null],[8,"id",0],[1,"aria-selected",0],[1,"aria-disabled",0],[2,"mat-option-disabled",null]],[[null,"click"],[null,"keydown"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==_._24(l,1)._selectViaInteraction()&&t}if("keydown"===n){t=!1!==_._24(l,1)._handleKeydown(u)&&t}return t},o.j,o.k)),_._22(49152,[[1,4]],0,d._32,[_.Q,[2,d._33],[2,d._16]],{value:[0,"value"]},null),_._22(16384,null,0,d._15,[[2,d._16],_.Q],null,null),(l()(),_._23(0,["\n ","\n "]))],function(l,n){l(n,1,0,n.context.$implicit.value)},function(l,n){l(n,0,0,_._24(n,1)._getTabIndex(),_._24(n,1).selected,_._24(n,1).multiple,_._24(n,1).active,_._24(n,1).id,_._24(n,1).selected.toString(),_._24(n,1).disabled.toString(),_._24(n,1).disabled),l(n,3,0,n.context.$implicit.display)})}function a(l){return _._20(0,[_._42(0,r.s,[_.h]),(l()(),_._23(null,["\n "])),(l()(),_._21(0,null,null,62,"div",[["class","row cart-wrapper"]],null,null,null,null,null)),(l()(),_._23(null,["\n "])),(l()(),_._26(16777216,null,null,1,null,t)),_._22(16384,null,0,r.k,[_._13,_._14],{ngIf:[0,"ngIf"]},null),(l()(),_._23(null,["\n "])),(l()(),_._21(0,null,null,56,"div",[["class","col-xs-7 start-xs"]],null,null,null,null,null)),(l()(),_._23(null,["\n "])),(l()(),_._21(0,null,null,1,"h4",[],null,null,null,null,null)),(l()(),_._23(null,["",""])),(l()(),_._23(null,["\n "])),(l()(),_._21(0,null,null,7,"p",[],null,null,null,null,null)),(l()(),_._21(0,null,null,2,"small",[],null,null,null,null,null)),(l()(),_._23(null,["",""])),_._43(3),(l()(),_._23(null,["\n "])),(l()(),_._21(0,null,null,2,"small",[["class","old-price"]],null,null,null,null,null)),(l()(),_._23(null,["",""])),_._43(3),(l()(),_._23(null,["\n "])),(l()(),_._21(0,null,null,41,"form",[["novalidate",""]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"ngSubmit"],[null,"submit"],[null,"reset"]],function(l,n,u){var t=!0,e=l.component;if("submit"===n){t=!1!==_._24(l,23).onSubmit(u)&&t}if("reset"===n){t=!1!==_._24(l,23).onReset()&&t}if("ngSubmit"===n){t=!1!==e.onUpdateCart()&&t}return t},null,null)),_._22(16384,null,0,s.n,[],null,null),_._22(540672,null,0,s.i,[[8,null],[8,null]],{form:[0,"form"]},{ngSubmit:"ngSubmit"}),_._36(2048,null,s.o,null,[s.i]),_._22(16384,null,0,s.p,[s.o],null,null),(l()(),_._23(null,["\n "])),(l()(),_._21(0,null,null,5,"input",[["formControlName","item"],["type","hidden"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"ngModelChange"],[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var t=!0,e=l.component;if("input"===n){t=!1!==_._24(l,28)._handleInput(u.target.value)&&t}if("blur"===n){t=!1!==_._24(l,28).onTouched()&&t}if("compositionstart"===n){t=!1!==_._24(l,28)._compositionStart()&&t}if("compositionend"===n){t=!1!==_._24(l,28)._compositionEnd(u.target.value)&&t}if("ngModelChange"===n){t=!1!==(e.cartItem.val.item=u)&&t}return t},null,null)),_._22(16384,null,0,s.q,[_.P,_.Q,[2,s.r]],null,null),_._36(1024,null,s.f,function(l){return[l]},[s.q]),_._22(671744,null,0,s.s,[[3,s.o],[8,null],[8,null],[2,s.f]],{name:[0,"name"],model:[1,"model"]},{update:"ngModelChange"}),_._36(2048,null,s.g,null,[s.s]),_._22(16384,null,0,s.t,[s.g],null,null),(l()(),_._23(null,["\n "])),(l()(),_._21(0,null,null,11,"md-select",[["class","mat-select"],["formControlName","quantity"],["placeholder","Quantity"],["role","listbox"]],[[1,"tabindex",0],[1,"aria-label",0],[1,"aria-labelledby",0],[1,"aria-required",0],[1,"aria-disabled",0],[1,"aria-invalid",0],[1,"aria-owns",0],[2,"mat-select-disabled",null],[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"ngModelChange"],[null,"keydown"],[null,"blur"]],function(l,n,u){var t=!0,e=l.component;if("keydown"===n){t=!1!==_._24(l,38)._handleClosedKeydown(u)&&t}if("blur"===n){t=!1!==_._24(l,38)._onBlur()&&t}if("ngModelChange"===n){t=!1!==(e.cartItem.val.quantity=u)&&t}return t},o.l,o.m)),_._22(16384,null,0,d._15,[[2,d._16],_.Q],null,null),_._22(671744,null,0,s.s,[[3,s.o],[8,null],[8,null],[8,null]],{name:[0,"name"],model:[1,"model"]},{update:"ngModelChange"}),_._36(2048,null,s.g,null,[s.s]),_._22(1294336,null,2,d._79,[d.e,_._18,_._25,_.Q,[2,d._54],[2,s.g],[8,null],[2,d._66]],{placeholder:[0,"placeholder"]},null),_._35(603979776,1,{options:1}),_._35(603979776,2,{optionGroups:1}),_._22(16384,null,0,s.t,[s.g],null,null),(l()(),_._23(0,["\n "])),(l()(),_._26(16777216,null,0,1,null,e)),_._22(802816,null,0,r.j,[_._13,_._14,_.l],{ngForOf:[0,"ngForOf"]},null),(l()(),_._23(0,["\n "])),(l()(),_._23(null,["\n "])),(l()(),_._21(0,null,null,0,"br",[],null,null,null,null,null)),(l()(),_._23(null,["\n "])),(l()(),_._21(0,null,null,12,"p",[],null,null,null,null,null)),(l()(),_._23(null,["\n "])),(l()(),_._21(0,null,null,2,"small",[],null,null,null,null,null)),(l()(),_._23(null,["Sub-Total: ",""])),_._43(3),(l()(),_._23(null,["\n \n "])),(l()(),_._21(0,null,null,5,"button",[["class","mat-button mat-raised-button"],["color","accent"],["md-button",""],["md-raised-button",""]],[[8,"disabled",0]],null,null,o.n,o.o)),_._22(16384,null,0,d._15,[[2,d._16],_.Q],null,null),_._22(180224,null,0,d._35,[_._25,_.Q,d.b,d.l],{disabled:[0,"disabled"],color:[1,"color"]},null),_._22(16384,null,0,d._18,[],null,null),_._22(16384,null,0,d._20,[],null,null),(l()(),_._23(0,["\n UPDATE CART\n "])),(l()(),_._23(null,["\n "])),(l()(),_._23(null,["\n "])),(l()(),_._23(null,["\n "])),(l()(),_._23(null,["\n "])),(l()(),_._23(null,["\n "])),(l()(),_._21(0,null,null,0,"br",[],null,null,null,null,null)),(l()(),_._23(null,["\n "]))],function(l,n){var u=n.component;l(n,5,0,u.cartItem),l(n,23,0,u.updateCartForm);l(n,30,0,"item",u.cartItem.val.item);l(n,36,0,"quantity",u.cartItem.val.quantity);l(n,38,0,"Quantity"),l(n,44,0,u.numbers);l(n,57,0,u.updateCartForm.pristine,"accent")},function(l,n){var u=n.component;l(n,10,0,u.cartItem.val.item.name),l(n,14,0,_._44(n,14,0,l(n,15,0,_._24(n,0),u.cartItem.val.item.price,"USD",!0))),l(n,18,0,_._44(n,18,0,l(n,19,0,_._24(n,0),u.cartItem.val.item.old_price,"USD",!0))),l(n,21,0,_._24(n,25).ngClassUntouched,_._24(n,25).ngClassTouched,_._24(n,25).ngClassPristine,_._24(n,25).ngClassDirty,_._24(n,25).ngClassValid,_._24(n,25).ngClassInvalid,_._24(n,25).ngClassPending),l(n,27,0,_._24(n,32).ngClassUntouched,_._24(n,32).ngClassTouched,_._24(n,32).ngClassPristine,_._24(n,32).ngClassDirty,_._24(n,32).ngClassValid,_._24(n,32).ngClassInvalid,_._24(n,32).ngClassPending),l(n,34,1,[_._24(n,38).tabIndex,_._24(n,38)._ariaLabel,_._24(n,38).ariaLabelledby,_._24(n,38).required.toString(),_._24(n,38).disabled.toString(),(null==_._24(n,38)._control?null:_._24(n,38)._control.invalid)||"false",_._24(n,38)._optionIds,_._24(n,38).disabled,_._24(n,41).ngClassUntouched,_._24(n,41).ngClassTouched,_._24(n,41).ngClassPristine,_._24(n,41).ngClassDirty,_._24(n,41).ngClassValid,_._24(n,41).ngClassInvalid,_._24(n,41).ngClassPending]),l(n,52,0,_._44(n,52,0,l(n,53,0,_._24(n,0),u.cartItem.val.quantity*u.cartItem.val.item.price,"USD",!0))),l(n,55,0,_._24(n,57).disabled||null)})}function i(l){return _._20(0,[(l()(),_._21(0,null,null,1,"apfem-cart-item",[],null,null,null,a,f)),_._22(114688,null,0,c.a,[],null,null)],function(l,n){l(n,1,0)},null)}var _=u("3j3K"),r=u("2Je8"),o=u("ZWsw"),d=u("fYnu"),c=u("3fiE"),s=u("NVOs");u.d(n,"b",function(){return f}),n.a=a;var m=[".cart-wrapper[_ngcontent-%COMP%]{border:1px solid #eee; background-color:#fff; border-radius:4px;}"],f=_._19({encapsulation:0,styles:m,data:{}});_._27("apfem-cart-item",c.a,i,{cartItem:"cartItem"},{},[])},"e4e+":function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=function(){function l(){}return l}()},sUip:function(l,n,u){"use strict";var t=u("RQxm");u.d(n,"a",function(){return e});var e=(t.b,function(){function l(){}return l}())}});
--------------------------------------------------------------------------------
/docs/assets/bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daviskoko/angular-firebase-ecommerce/8c72f065d7f2fe166fbbaf2638872f43ad2a246a/docs/assets/bg.jpg
--------------------------------------------------------------------------------
/docs/bg.e88a2d4544db10e6bdcf.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daviskoko/angular-firebase-ecommerce/8c72f065d7f2fe166fbbaf2638872f43ad2a246a/docs/bg.e88a2d4544db10e6bdcf.jpg
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | APFEM SHOP
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/docs/inline.4f04594155dcd0da1dd8.bundle.js:
--------------------------------------------------------------------------------
1 | !function(e){function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}var n=window.webpackJsonp;window.webpackJsonp=function(t,a,c){for(var u,i,f,d=0,l=[];dthis.getCurrentIndex()?u.NEXT:u.PREV),n&&n!==this.currentSlide&&this.goNext(n,l)},n.prototype.goNext=function(n,l){this.destroyed||(n.direction=l,n.active=!0,this.currentSlide&&(this.currentSlide.direction=l,this.currentSlide.active=!1),this.currentSlide=n,this.restartTimer())},n.prototype.getSlideByIndex=function(n){for(var l=this.slides.length,t=0;t0&&(this.currentInterval=setInterval(function(){var l=+n.interval;n.isPlaying&&!isNaN(n.interval)&&l>0&&n.slides.length?n.next():n.pause()},l))},n.prototype.resetTimer=function(){this.currentInterval&&(clearInterval(this.currentInterval),this.currentInterval=null)},n.prototype.play=function(){this.isPlaying||(this.isPlaying=!0,this.restartTimer())},n.prototype.pause=function(){this.noPause||(this.isPlaying=!1,this.resetTimer())},n.prototype.addSlide=function(n){n.index=this.slides.length,this.slides.push(n),1===this.slides.length||n.active?(this.select(this.slides[this.slides.length-1]),1===this.slides.length&&this.play()):n.active=!1},n.prototype.removeSlide=function(n){if(this.slides.splice(n.index,1),0===this.slides.length)return void(this.currentSlide=null);for(var l=0;l.item{display:none;position:relative;transition:left .6s ease-in-out}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;left:0;bottom:0;width:15%;opacity:.5;filter:alpha(opacity=50);font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.8)}.carousel-control.right{left:auto;right:0}.carousel-control:focus,.carousel-control:hover{outline:none;color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;margin-top:-10px;margin-left:-10px;font-family:serif}.carousel-control .icon-prev:before{content:"\2039"}.carousel-control .icon-next:before{content:"\203A"}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;margin-left:-30%;padding-left:0;list-style:none;text-align:center}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;border:1px solid #fff;border-radius:10px;cursor:pointer;background-color:#000\9;background-color:transparent}.carousel-indicators .active{margin:0;width:12px;height:12px;background-color:#fff}.carousel-caption{position:absolute;left:15%;right:15%;bottom:20px;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}.carousel-icon{font-size:5vmin;cursor:pointer;width:auto!important;height:auto!important}.mat-elevation-z0{box-shadow:0 0 0 0 rgba(0,0,0,.2),0 0 0 0 rgba(0,0,0,.14),0 0 0 0 rgba(0,0,0,.12)}.mat-elevation-z1{box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12)}.mat-elevation-z2{box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12)}.mat-elevation-z3{box-shadow:0 3px 3px -2px rgba(0,0,0,.2),0 3px 4px 0 rgba(0,0,0,.14),0 1px 8px 0 rgba(0,0,0,.12)}.mat-elevation-z4{box-shadow:0 2px 4px -1px rgba(0,0,0,.2),0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12)}.mat-elevation-z5{box-shadow:0 3px 5px -1px rgba(0,0,0,.2),0 5px 8px 0 rgba(0,0,0,.14),0 1px 14px 0 rgba(0,0,0,.12)}.mat-elevation-z6{box-shadow:0 3px 5px -1px rgba(0,0,0,.2),0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12)}.mat-elevation-z7{box-shadow:0 4px 5px -2px rgba(0,0,0,.2),0 7px 10px 1px rgba(0,0,0,.14),0 2px 16px 1px rgba(0,0,0,.12)}.mat-elevation-z8{box-shadow:0 5px 5px -3px rgba(0,0,0,.2),0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12)}.mat-elevation-z9{box-shadow:0 5px 6px -3px rgba(0,0,0,.2),0 9px 12px 1px rgba(0,0,0,.14),0 3px 16px 2px rgba(0,0,0,.12)}.mat-elevation-z10{box-shadow:0 6px 6px -3px rgba(0,0,0,.2),0 10px 14px 1px rgba(0,0,0,.14),0 4px 18px 3px rgba(0,0,0,.12)}.mat-elevation-z11{box-shadow:0 6px 7px -4px rgba(0,0,0,.2),0 11px 15px 1px rgba(0,0,0,.14),0 4px 20px 3px rgba(0,0,0,.12)}.mat-elevation-z12{box-shadow:0 7px 8px -4px rgba(0,0,0,.2),0 12px 17px 2px rgba(0,0,0,.14),0 5px 22px 4px rgba(0,0,0,.12)}.mat-elevation-z13{box-shadow:0 7px 8px -4px rgba(0,0,0,.2),0 13px 19px 2px rgba(0,0,0,.14),0 5px 24px 4px rgba(0,0,0,.12)}.mat-elevation-z14{box-shadow:0 7px 9px -4px rgba(0,0,0,.2),0 14px 21px 2px rgba(0,0,0,.14),0 5px 26px 4px rgba(0,0,0,.12)}.mat-elevation-z15{box-shadow:0 8px 9px -5px rgba(0,0,0,.2),0 15px 22px 2px rgba(0,0,0,.14),0 6px 28px 5px rgba(0,0,0,.12)}.mat-elevation-z16{box-shadow:0 8px 10px -5px rgba(0,0,0,.2),0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12)}.mat-elevation-z17{box-shadow:0 8px 11px -5px rgba(0,0,0,.2),0 17px 26px 2px rgba(0,0,0,.14),0 6px 32px 5px rgba(0,0,0,.12)}.mat-elevation-z18{box-shadow:0 9px 11px -5px rgba(0,0,0,.2),0 18px 28px 2px rgba(0,0,0,.14),0 7px 34px 6px rgba(0,0,0,.12)}.mat-elevation-z19{box-shadow:0 9px 12px -6px rgba(0,0,0,.2),0 19px 29px 2px rgba(0,0,0,.14),0 7px 36px 6px rgba(0,0,0,.12)}.mat-elevation-z20{box-shadow:0 10px 13px -6px rgba(0,0,0,.2),0 20px 31px 3px rgba(0,0,0,.14),0 8px 38px 7px rgba(0,0,0,.12)}.mat-elevation-z21{box-shadow:0 10px 13px -6px rgba(0,0,0,.2),0 21px 33px 3px rgba(0,0,0,.14),0 8px 40px 7px rgba(0,0,0,.12)}.mat-elevation-z22{box-shadow:0 10px 14px -6px rgba(0,0,0,.2),0 22px 35px 3px rgba(0,0,0,.14),0 8px 42px 7px rgba(0,0,0,.12)}.mat-elevation-z23{box-shadow:0 11px 14px -7px rgba(0,0,0,.2),0 23px 36px 3px rgba(0,0,0,.14),0 9px 44px 8px rgba(0,0,0,.12)}.mat-elevation-z24{box-shadow:0 11px 15px -7px rgba(0,0,0,.2),0 24px 38px 3px rgba(0,0,0,.14),0 9px 46px 8px rgba(0,0,0,.12)}.mat-h1,.mat-headline,.mat-typography h1{font:400 24px/32px Roboto,Helvetica Neue,sans-serif;margin:0 0 16px}.mat-h2,.mat-title,.mat-typography h2{font:500 20px/32px Roboto,Helvetica Neue,sans-serif;margin:0 0 16px}.mat-h3,.mat-subheading-2,.mat-typography h3{font:400 16px/28px Roboto,Helvetica Neue,sans-serif;margin:0 0 16px}.mat-h4,.mat-subheading-1,.mat-typography h4{font:400 15px/24px Roboto,Helvetica Neue,sans-serif;margin:0 0 16px}.mat-h5,.mat-typography h5{font-size:11.62px}.mat-h5,.mat-h6,.mat-typography h5,.mat-typography h6{font-weight:400;font-family:Roboto,Helvetica Neue,sans-serif;line-height:20px;margin:0 0 12px}.mat-h6,.mat-typography h6{font-size:9.38px}.mat-body-2,.mat-body-strong{font:500 14px/24px Roboto,Helvetica Neue,sans-serif}.mat-body,.mat-body-1,.mat-typography{font:400 14px/20px Roboto,Helvetica Neue,sans-serif}.mat-body-1 p,.mat-body p,.mat-typography p{margin:0 0 12px}.mat-caption,.mat-small{font:400 12px/20px Roboto,Helvetica Neue,sans-serif}.mat-display-4,.mat-typography .mat-display-4{font:300 112px/112px Roboto,Helvetica Neue,sans-serif;margin:0 0 56px;letter-spacing:-.05em}.mat-display-3,.mat-typography .mat-display-3{font:400 56px/56px Roboto,Helvetica Neue,sans-serif;margin:0 0 64px;letter-spacing:-.02em}.mat-display-2,.mat-typography .mat-display-2{font:400 45px/48px Roboto,Helvetica Neue,sans-serif;margin:0 0 64px;letter-spacing:-.005em}.mat-display-1,.mat-typography .mat-display-1{font:400 34px/40px Roboto,Helvetica Neue,sans-serif;margin:0 0 64px}.mat-button,.mat-icon-button,.mat-raised-button{font-family:Roboto,Helvetica Neue,sans-serif;font-size:14px;font-weight:500}.mat-button-toggle,.mat-card{font-family:Roboto,Helvetica Neue,sans-serif}.mat-card-title{font-size:24px;font-weight:400}.mat-card-content,.mat-card-header .mat-card-title,.mat-card-subtitle{font-size:14px}.mat-checkbox{font-family:Roboto,Helvetica Neue,sans-serif}.mat-checkbox-layout .mat-checkbox-label{line-height:24px}.mat-chip:not(.mat-basic-chip){font-size:13px;line-height:16px}.mat-calendar{font-family:Roboto,Helvetica Neue,sans-serif}.mat-calendar-body{font-size:13px}.mat-calendar-body-label,.mat-calendar-period-button{font-size:14px;font-weight:500}.mat-calendar-table-header th{font-size:11px;font-weight:400}.mat-dialog-title{font:500 20px/32px Roboto,Helvetica Neue,sans-serif}.mat-grid-tile-footer,.mat-grid-tile-header{font-size:14px}.mat-grid-tile-footer .mat-line,.mat-grid-tile-header .mat-line{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;box-sizing:border-box}.mat-grid-tile-footer .mat-line:nth-child(n+2),.mat-grid-tile-header .mat-line:nth-child(n+2){font-size:12px}.mat-input-container{font:400 inherit/1.125 Roboto,Helvetica Neue,sans-serif}.mat-input-wrapper{padding-bottom:1.296875em}.mat-input-prefix .mat-datepicker-toggle,.mat-input-prefix .mat-icon,.mat-input-suffix .mat-datepicker-toggle,.mat-input-suffix .mat-icon{font-size:150%}.mat-input-prefix .mat-icon-button,.mat-input-suffix .mat-icon-button{height:1.5em;width:1.5em}.mat-input-prefix .mat-icon-button .mat-icon,.mat-input-suffix .mat-icon-button .mat-icon{line-height:1.5}.mat-input-infix{padding:.4375em 0;border-top:.84375em solid transparent}.mat-input-element:-webkit-autofill+.mat-input-placeholder-wrapper .mat-float{-webkit-transform:translateY(-1.28125em) scale(.75) perspective(100px) translateZ(.001px);transform:translateY(-1.28125em) scale(.75) perspective(100px) translateZ(.001px);-ms-transform:translateY(-1.28125em) scale(.75);width:133.33333333%}.mat-input-placeholder-wrapper{top:-.84375em;padding-top:.84375em}.mat-input-placeholder{top:1.28125em}.mat-focused .mat-input-placeholder.mat-float,.mat-input-placeholder.mat-float:not(.mat-empty){-webkit-transform:translateY(-1.28125em) scale(.75) perspective(100px) translateZ(.001px);transform:translateY(-1.28125em) scale(.75) perspective(100px) translateZ(.001px);-ms-transform:translateY(-1.28125em) scale(.75);width:133.33333333%}.mat-input-underline{bottom:1.296875em}.mat-input-subscript-wrapper{font-size:75%;margin-top:.60416667em;top:calc(100% - 1.72916667em)}.mat-menu-item{font-size:16px}.mat-menu-item,.mat-radio-button,.mat-select{font-family:Roboto,Helvetica Neue,sans-serif}.mat-select-trigger{font-size:16px}.mat-slide-toggle-content{font:400 14px/20px Roboto,Helvetica Neue,sans-serif}.mat-slider-thumb-label-text{font-size:12px;font-weight:500}.mat-tab-group,.mat-tab-label,.mat-tab-link{font-family:Roboto,Helvetica Neue,sans-serif}.mat-tab-label,.mat-tab-link{font-size:14px;font-weight:500}.mat-toolbar,.mat-toolbar h1,.mat-toolbar h2,.mat-toolbar h3,.mat-toolbar h4,.mat-toolbar h5,.mat-toolbar h6{font:500 20px/32px Roboto,Helvetica Neue,sans-serif;margin:0}.mat-tooltip{font-size:10px;padding-top:6px;padding-bottom:6px}.mat-list-item,.mat-tooltip{font-family:Roboto,Helvetica Neue,sans-serif}.mat-list .mat-list-item,.mat-nav-list .mat-list-item{font-size:16px}.mat-list .mat-list-item .mat-line,.mat-nav-list .mat-list-item .mat-line{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;box-sizing:border-box}.mat-list .mat-list-item .mat-line:nth-child(n+2),.mat-nav-list .mat-list-item .mat-line:nth-child(n+2){font-size:14px}.mat-list .mat-subheader,.mat-nav-list .mat-subheader{font:500 14px/24px Roboto,Helvetica Neue,sans-serif}.mat-list[dense] .mat-list-item,.mat-nav-list[dense] .mat-list-item{font-size:12px}.mat-list[dense] .mat-list-item .mat-line,.mat-nav-list[dense] .mat-list-item .mat-line{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;box-sizing:border-box}.mat-list[dense] .mat-list-item .mat-line:nth-child(n+2),.mat-nav-list[dense] .mat-list-item .mat-line:nth-child(n+2){font-size:12px}.mat-list[dense] .mat-subheader,.mat-nav-list[dense] .mat-subheader{font:500 12px Roboto,Helvetica Neue,sans-serif}.mat-option{font-size:16px}.mat-option,.mat-simple-snackbar{font-family:Roboto,Helvetica Neue,sans-serif}.mat-simple-snackbar{font-size:14px}.mat-simple-snackbar-action{line-height:1;font-family:inherit;font-size:inherit;font-weight:500}.mat-ripple{overflow:hidden}.mat-ripple.mat-ripple-unbounded{overflow:visible}.mat-ripple-element{position:absolute;border-radius:50%;pointer-events:none;transition:opacity,-webkit-transform 0ms cubic-bezier(0,0,.2,1);transition:opacity,transform 0ms cubic-bezier(0,0,.2,1);transition:opacity,transform 0ms cubic-bezier(0,0,.2,1),-webkit-transform 0ms cubic-bezier(0,0,.2,1);-webkit-transform:scale(0);transform:scale(0)}.mat-option{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;line-height:48px;height:48px;padding:0 16px;text-align:left;text-decoration:none;position:relative;cursor:pointer;outline:none}.mat-option[disabled]{cursor:default}[dir=rtl] .mat-option{text-align:right}.mat-option .mat-icon{margin-right:16px}[dir=rtl] .mat-option .mat-icon{margin-left:16px;margin-right:0}.mat-option[aria-disabled=true]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default}.mat-optgroup .mat-option:not(.mat-option-multiple){padding-left:32px}[dir=rtl] .mat-optgroup .mat-option:not(.mat-option-multiple){padding-left:16px;padding-right:32px}.mat-option-ripple{position:absolute;top:0;left:0;bottom:0;right:0;pointer-events:none}@media screen and (-ms-high-contrast:active){.mat-option-ripple{opacity:.5}}.mat-option-pseudo-checkbox{margin-right:8px}[dir=rtl] .mat-option-pseudo-checkbox{margin-left:8px;margin-right:0}.mat-optgroup-label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;line-height:48px;height:48px;padding:0 16px;text-align:left;text-decoration:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default;font-weight:700;font-size:14px}.mat-optgroup-label[disabled]{cursor:default}[dir=rtl] .mat-optgroup-label{text-align:right}.mat-optgroup-label .mat-icon{margin-right:16px}[dir=rtl] .mat-optgroup-label .mat-icon{margin-left:16px;margin-right:0}.cdk-visually-hidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;text-transform:none;width:1px}.cdk-global-overlay-wrapper,.cdk-overlay-container{pointer-events:none;top:0;left:0;height:100%;width:100%}.cdk-overlay-container{position:fixed;z-index:1000}.cdk-global-overlay-wrapper{display:-webkit-box;display:-ms-flexbox;display:flex;position:absolute;z-index:1000}.cdk-overlay-pane{box-sizing:border-box}.cdk-overlay-backdrop,.cdk-overlay-pane{position:absolute;pointer-events:auto;z-index:1000}.cdk-overlay-backdrop{top:0;bottom:0;left:0;right:0;transition:opacity .4s cubic-bezier(.25,.8,.25,1);opacity:0}.cdk-overlay-backdrop.cdk-overlay-backdrop-showing{opacity:.48}.cdk-overlay-dark-backdrop{background:rgba(0,0,0,.6)}.cdk-overlay-transparent-backdrop{background:none}.cdk-global-scrollblock{position:fixed;width:100%;overflow-y:scroll}.mat-ripple-element{background-color:rgba(0,0,0,.1)}.mat-option{color:rgba(0,0,0,.87)}.mat-option:focus:not(.mat-option-disabled),.mat-option:hover:not(.mat-option-disabled){background:rgba(0,0,0,.04)}.mat-option.mat-selected.mat-primary,.mat-primary .mat-option.mat-selected{color:#e91e63}.mat-accent .mat-option.mat-selected,.mat-option.mat-selected.mat-accent{color:#ad1457}.mat-option.mat-selected.mat-warn,.mat-warn .mat-option.mat-selected{color:#f44336}.mat-option.mat-active,.mat-option.mat-selected:not(.mat-option-multiple){background:rgba(0,0,0,.04)}.mat-option.mat-active{color:rgba(0,0,0,.87)}.mat-option.mat-option-disabled{color:rgba(0,0,0,.38)}.mat-optgroup-label{color:rgba(0,0,0,.54)}.mat-optgroup-disabled .mat-optgroup-label{color:rgba(0,0,0,.38)}.mat-pseudo-checkbox{color:rgba(0,0,0,.54)}.mat-pseudo-checkbox:after{color:#fafafa}.mat-primary .mat-pseudo-checkbox-checked,.mat-primary .mat-pseudo-checkbox-indeterminate,.mat-pseudo-checkbox-checked.mat-primary,.mat-pseudo-checkbox-indeterminate.mat-primary{background:#e91e63}.mat-accent .mat-pseudo-checkbox-checked,.mat-accent .mat-pseudo-checkbox-indeterminate,.mat-pseudo-checkbox-checked.mat-accent,.mat-pseudo-checkbox-indeterminate.mat-accent{background:#ad1457}.mat-pseudo-checkbox-checked.mat-warn,.mat-pseudo-checkbox-indeterminate.mat-warn,.mat-warn .mat-pseudo-checkbox-checked,.mat-warn .mat-pseudo-checkbox-indeterminate{background:#f44336}.mat-pseudo-checkbox-checked.mat-pseudo-checkbox-disabled,.mat-pseudo-checkbox-indeterminate.mat-pseudo-checkbox-disabled{background:#b0b0b0}.mat-app-background{background-color:#fafafa}.mat-theme-loaded-marker{display:none}.mat-autocomplete-panel,.mat-autocomplete-panel .mat-option.mat-selected:not(.mat-active):not(:hover){background:#fff;color:rgba(0,0,0,.87)}.mat-button,.mat-icon-button{background:transparent}.mat-button.mat-primary .mat-button-focus-overlay,.mat-icon-button.mat-primary .mat-button-focus-overlay{background-color:rgba(233,30,99,.12)}.mat-button.mat-accent .mat-button-focus-overlay,.mat-icon-button.mat-accent .mat-button-focus-overlay{background-color:rgba(173,20,87,.12)}.mat-button.mat-warn .mat-button-focus-overlay,.mat-icon-button.mat-warn .mat-button-focus-overlay{background-color:rgba(244,67,54,.12)}.mat-button[disabled] .mat-button-focus-overlay,.mat-icon-button[disabled] .mat-button-focus-overlay{background-color:transparent}.mat-button.mat-primary,.mat-icon-button.mat-primary{color:#e91e63}.mat-button.mat-accent,.mat-icon-button.mat-accent{color:#ad1457}.mat-button.mat-warn,.mat-icon-button.mat-warn{color:#f44336}.mat-button.mat-accent[disabled],.mat-button.mat-primary[disabled],.mat-button.mat-warn[disabled],.mat-button[disabled][disabled],.mat-icon-button.mat-accent[disabled],.mat-icon-button.mat-primary[disabled],.mat-icon-button.mat-warn[disabled],.mat-icon-button[disabled][disabled]{color:rgba(0,0,0,.38)}.mat-fab,.mat-mini-fab,.mat-raised-button{color:rgba(0,0,0,.87);background-color:#fff}.mat-fab.mat-primary,.mat-mini-fab.mat-primary,.mat-raised-button.mat-primary{color:#fff}.mat-fab.mat-accent,.mat-mini-fab.mat-accent,.mat-raised-button.mat-accent{color:hsla(0,0%,100%,.87)}.mat-fab.mat-warn,.mat-mini-fab.mat-warn,.mat-raised-button.mat-warn{color:#fff}.mat-fab.mat-accent[disabled],.mat-fab.mat-primary[disabled],.mat-fab.mat-warn[disabled],.mat-fab[disabled][disabled],.mat-mini-fab.mat-accent[disabled],.mat-mini-fab.mat-primary[disabled],.mat-mini-fab.mat-warn[disabled],.mat-mini-fab[disabled][disabled],.mat-raised-button.mat-accent[disabled],.mat-raised-button.mat-primary[disabled],.mat-raised-button.mat-warn[disabled],.mat-raised-button[disabled][disabled]{color:rgba(0,0,0,.38)}.mat-fab.mat-primary,.mat-mini-fab.mat-primary,.mat-raised-button.mat-primary{background-color:#e91e63}.mat-fab.mat-accent,.mat-mini-fab.mat-accent,.mat-raised-button.mat-accent{background-color:#ad1457}.mat-fab.mat-warn,.mat-mini-fab.mat-warn,.mat-raised-button.mat-warn{background-color:#f44336}.mat-fab.mat-accent[disabled],.mat-fab.mat-primary[disabled],.mat-fab.mat-warn[disabled],.mat-fab[disabled][disabled],.mat-mini-fab.mat-accent[disabled],.mat-mini-fab.mat-primary[disabled],.mat-mini-fab.mat-warn[disabled],.mat-mini-fab[disabled][disabled],.mat-raised-button.mat-accent[disabled],.mat-raised-button.mat-primary[disabled],.mat-raised-button.mat-warn[disabled],.mat-raised-button[disabled][disabled]{background-color:rgba(0,0,0,.12)}.mat-fab.mat-accent .mat-ripple-element,.mat-fab.mat-primary .mat-ripple-element,.mat-fab.mat-warn .mat-ripple-element,.mat-mini-fab.mat-accent .mat-ripple-element,.mat-mini-fab.mat-primary .mat-ripple-element,.mat-mini-fab.mat-warn .mat-ripple-element,.mat-raised-button.mat-accent .mat-ripple-element,.mat-raised-button.mat-primary .mat-ripple-element,.mat-raised-button.mat-warn .mat-ripple-element{background-color:hsla(0,0%,100%,.2)}.mat-button.mat-primary .mat-ripple-element{background-color:rgba(233,30,99,.1)}.mat-button.mat-accent .mat-ripple-element{background-color:rgba(173,20,87,.1)}.mat-button.mat-warn .mat-ripple-element{background-color:rgba(244,67,54,.1)}.mat-icon-button.mat-primary .mat-ripple-element{background-color:rgba(233,30,99,.2)}.mat-icon-button.mat-accent .mat-ripple-element{background-color:rgba(173,20,87,.2)}.mat-icon-button.mat-warn .mat-ripple-element{background-color:rgba(244,67,54,.2)}.mat-button-toggle{color:rgba(0,0,0,.38)}.mat-button-toggle.cdk-focused .mat-button-toggle-focus-overlay{background-color:rgba(0,0,0,.06)}.mat-button-toggle-checked{background-color:#e0e0e0;color:#000}.mat-button-toggle-disabled{background-color:#eee;color:rgba(0,0,0,.38)}.mat-button-toggle-disabled.mat-button-toggle-checked{background-color:#bdbdbd}.mat-card{background:#fff;color:rgba(0,0,0,.87)}.mat-card-subtitle{color:rgba(0,0,0,.54)}.mat-checkbox-frame{border-color:rgba(0,0,0,.54)}.mat-checkbox-checkmark{fill:#fafafa}.mat-checkbox-checkmark-path{stroke:#fafafa!important}.mat-checkbox-mixedmark{background-color:#fafafa}.mat-checkbox-checked.mat-primary .mat-checkbox-background,.mat-checkbox-indeterminate.mat-primary .mat-checkbox-background{background-color:#e91e63}.mat-checkbox-checked.mat-accent .mat-checkbox-background,.mat-checkbox-indeterminate.mat-accent .mat-checkbox-background{background-color:#ad1457}.mat-checkbox-checked.mat-warn .mat-checkbox-background,.mat-checkbox-indeterminate.mat-warn .mat-checkbox-background{background-color:#f44336}.mat-checkbox-disabled.mat-checkbox-checked .mat-checkbox-background,.mat-checkbox-disabled.mat-checkbox-indeterminate .mat-checkbox-background{background-color:#b0b0b0}.mat-checkbox-disabled:not(.mat-checkbox-checked) .mat-checkbox-frame{border-color:#b0b0b0}.mat-checkbox-disabled .mat-checkbox-label{color:#b0b0b0}.mat-checkbox:not(.mat-checkbox-disabled).mat-primary .mat-checkbox-ripple .mat-ripple-element{background-color:rgba(233,30,99,.26)}.mat-checkbox:not(.mat-checkbox-disabled).mat-accent .mat-checkbox-ripple .mat-ripple-element{background-color:rgba(173,20,87,.26)}.mat-checkbox:not(.mat-checkbox-disabled).mat-warn .mat-checkbox-ripple .mat-ripple-element{background-color:rgba(244,67,54,.26)}.mat-chip:not(.mat-basic-chip){background-color:#e0e0e0;color:rgba(0,0,0,.87)}.mat-chip.mat-chip-selected:not(.mat-basic-chip){background-color:gray;color:hsla(0,0%,100%,.87)}.mat-chip.mat-chip-selected:not(.mat-basic-chip).mat-primary{background-color:#e91e63;color:#fff}.mat-chip.mat-chip-selected:not(.mat-basic-chip).mat-accent{background-color:#ad1457;color:hsla(0,0%,100%,.87)}.mat-chip.mat-chip-selected:not(.mat-basic-chip).mat-warn{background-color:#f44336;color:#fff}.mat-datepicker-content{background-color:#fff}.mat-calendar-arrow{border-top-color:rgba(0,0,0,.54)}.mat-calendar-next-button,.mat-calendar-previous-button{color:rgba(0,0,0,.54)}.mat-calendar-table-header{color:rgba(0,0,0,.38)}.mat-calendar-table-header-divider:after{background:rgba(0,0,0,.12)}.mat-calendar-body-label{color:rgba(0,0,0,.54)}.mat-calendar-body-cell-content{color:rgba(0,0,0,.87);border-color:transparent}.mat-calendar-body-disabled>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected){color:rgba(0,0,0,.38)}.cdk-keyboard-focused .mat-calendar-body-active>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected),:not(.mat-calendar-body-disabled):hover>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected){background-color:rgba(0,0,0,.04)}.mat-calendar-body-selected{background-color:#e91e63;color:#fff}.mat-calendar-body-disabled>.mat-calendar-body-selected{background-color:rgba(233,30,99,.4)}.mat-calendar-body-today:not(.mat-calendar-body-selected){border-color:rgba(0,0,0,.38)}.mat-calendar-body-today.mat-calendar-body-selected{box-shadow:inset 0 0 0 1px #fff}.mat-calendar-body-disabled>.mat-calendar-body-today:not(.mat-calendar-body-selected){border-color:rgba(0,0,0,.18)}.mat-dialog-container{background:#fff;color:rgba(0,0,0,.87)}.mat-expansion-panel{background:#fff;color:#000}.mat-action-row{border-top-color:rgba(0,0,0,.12)}.mat-expansion-panel-header:focus,.mat-expansion-panel-header:hover{background:rgba(0,0,0,.04)}.mat-expansion-panel-header-title{color:rgba(0,0,0,.87)}.mat-expansion-indicator:after,.mat-expansion-panel-header-description{color:rgba(0,0,0,.54)}.mat-icon.mat-primary{color:#e91e63}.mat-icon.mat-accent{color:#ad1457}.mat-icon.mat-warn{color:#f44336}.mat-input-placeholder{color:rgba(0,0,0,.38)}.mat-focused .mat-input-placeholder{color:#e91e63}.mat-focused .mat-input-placeholder.mat-accent{color:#ad1457}.mat-focused .mat-input-placeholder.mat-warn{color:#f44336}.mat-input-element:disabled{color:rgba(0,0,0,.38)}.mat-focused .mat-input-placeholder.mat-float .mat-placeholder-required,input.mat-input-element:-webkit-autofill+.mat-input-placeholder .mat-placeholder-required{color:#ad1457}.mat-input-underline{background-color:rgba(0,0,0,.12)}.mat-input-ripple{background-color:#e91e63}.mat-input-ripple.mat-accent{background-color:#ad1457}.mat-input-ripple.mat-warn{background-color:#f44336}.mat-input-invalid .mat-input-placeholder,.mat-input-invalid .mat-input-placeholder.mat-accent,.mat-input-invalid .mat-input-placeholder.mat-float .mat-placeholder-required{color:#f44336}.mat-input-invalid .mat-input-ripple{background-color:#f44336}.mat-input-error{color:#f44336}.mat-list .mat-list-item,.mat-nav-list .mat-list-item{color:rgba(0,0,0,.87)}.mat-list .mat-subheader,.mat-nav-list .mat-subheader{color:rgba(0,0,0,.54)}.mat-divider{border-top-color:rgba(0,0,0,.12)}.mat-nav-list .mat-list-item{outline:none}.mat-nav-list .mat-list-item.mat-list-item-focus,.mat-nav-list .mat-list-item:hover{background:rgba(0,0,0,.04)}.mat-menu-content{background:#fff}.mat-menu-item{background:transparent;color:rgba(0,0,0,.87)}.mat-menu-item[disabled]{color:rgba(0,0,0,.38)}.mat-menu-item .mat-icon{color:rgba(0,0,0,.54);vertical-align:middle}.mat-menu-item:focus:not([disabled]),.mat-menu-item:hover:not([disabled]){background:rgba(0,0,0,.04)}.mat-progress-bar-background{background-image:url("data:image/svg+xml;charset=UTF-8,%3Csvg%20version%3D%271.1%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20xmlns%3Axlink%3D%27http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%27%20x%3D%270px%27%20y%3D%270px%27%20enable-background%3D%27new%200%200%205%202%27%20xml%3Aspace%3D%27preserve%27%20viewBox%3D%270%200%205%202%27%20preserveAspectRatio%3D%27none%20slice%27%3E%3Ccircle%20cx%3D%271%27%20cy%3D%271%27%20r%3D%271%27%20fill%3D%27%23f8bbd0%27%2F%3E%3C%2Fsvg%3E")}.mat-progress-bar-buffer{background-color:#f8bbd0}.mat-progress-bar-fill:after{background-color:#e91e63}.mat-progress-bar.mat-accent .mat-progress-bar-background{background-image:url("data:image/svg+xml;charset=UTF-8,%3Csvg%20version%3D%271.1%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20xmlns%3Axlink%3D%27http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%27%20x%3D%270px%27%20y%3D%270px%27%20enable-background%3D%27new%200%200%205%202%27%20xml%3Aspace%3D%27preserve%27%20viewBox%3D%270%200%205%202%27%20preserveAspectRatio%3D%27none%20slice%27%3E%3Ccircle%20cx%3D%271%27%20cy%3D%271%27%20r%3D%271%27%20fill%3D%27%23f8bbd0%27%2F%3E%3C%2Fsvg%3E")}.mat-progress-bar.mat-accent .mat-progress-bar-buffer{background-color:#f8bbd0}.mat-progress-bar.mat-accent .mat-progress-bar-fill:after{background-color:#ad1457}.mat-progress-bar.mat-warn .mat-progress-bar-background{background-image:url("data:image/svg+xml;charset=UTF-8,%3Csvg%20version%3D%271.1%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20xmlns%3Axlink%3D%27http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%27%20x%3D%270px%27%20y%3D%270px%27%20enable-background%3D%27new%200%200%205%202%27%20xml%3Aspace%3D%27preserve%27%20viewBox%3D%270%200%205%202%27%20preserveAspectRatio%3D%27none%20slice%27%3E%3Ccircle%20cx%3D%271%27%20cy%3D%271%27%20r%3D%271%27%20fill%3D%27%23ffcdd2%27%2F%3E%3C%2Fsvg%3E")}.mat-progress-bar.mat-warn .mat-progress-bar-buffer{background-color:#ffcdd2}.mat-progress-bar.mat-warn .mat-progress-bar-fill:after{background-color:#f44336}.mat-progress-spinner path,.mat-spinner path{stroke:#e91e63}.mat-progress-spinner.mat-accent path,.mat-spinner.mat-accent path{stroke:#ad1457}.mat-progress-spinner.mat-warn path,.mat-spinner.mat-warn path{stroke:#f44336}.mat-radio-outer-circle{border-color:rgba(0,0,0,.54)}.mat-radio-disabled .mat-radio-outer-circle{border-color:rgba(0,0,0,.38)}.mat-radio-disabled .mat-radio-inner-circle,.mat-radio-disabled .mat-radio-ripple .mat-ripple-element{background-color:rgba(0,0,0,.38)}.mat-radio-disabled .mat-radio-label-content{color:rgba(0,0,0,.38)}.mat-radio-button.mat-primary.mat-radio-checked .mat-radio-outer-circle{border-color:#e91e63}.mat-radio-button.mat-primary .mat-radio-inner-circle{background-color:#e91e63}.mat-radio-button.mat-primary .mat-radio-ripple .mat-ripple-element{background-color:rgba(233,30,99,.26)}.mat-radio-button.mat-accent.mat-radio-checked .mat-radio-outer-circle{border-color:#ad1457}.mat-radio-button.mat-accent .mat-radio-inner-circle{background-color:#ad1457}.mat-radio-button.mat-accent .mat-radio-ripple .mat-ripple-element{background-color:rgba(173,20,87,.26)}.mat-radio-button.mat-warn.mat-radio-checked .mat-radio-outer-circle{border-color:#f44336}.mat-radio-button.mat-warn .mat-radio-inner-circle{background-color:#f44336}.mat-radio-button.mat-warn .mat-radio-ripple .mat-ripple-element{background-color:rgba(244,67,54,.26)}.mat-select-arrow,.mat-select-trigger{color:rgba(0,0,0,.38)}.mat-select-underline{background-color:rgba(0,0,0,.12)}.mat-select-arrow,.mat-select-disabled .mat-select-value,.mat-select-trigger{color:rgba(0,0,0,.38)}.mat-select-content,.mat-select-panel-done-animating{background:#fff}.mat-select-value{color:rgba(0,0,0,.87)}.mat-select:focus:not(.mat-select-disabled).mat-primary .mat-select-arrow,.mat-select:focus:not(.mat-select-disabled).mat-primary .mat-select-trigger{color:#e91e63}.mat-select:focus:not(.mat-select-disabled).mat-primary .mat-select-underline{background-color:#e91e63}.mat-select:focus:not(.mat-select-disabled).mat-accent .mat-select-arrow,.mat-select:focus:not(.mat-select-disabled).mat-accent .mat-select-trigger{color:#ad1457}.mat-select:focus:not(.mat-select-disabled).mat-accent .mat-select-underline{background-color:#ad1457}.mat-select:focus:not(.mat-select-disabled).mat-warn .mat-select-arrow,.mat-select:focus:not(.mat-select-disabled).mat-warn .mat-select-trigger,.mat-select:not(:focus).ng-invalid.ng-touched:not(.mat-select-disabled) .mat-select-arrow,.mat-select:not(:focus).ng-invalid.ng-touched:not(.mat-select-disabled) .mat-select-trigger{color:#f44336}.mat-select:focus:not(.mat-select-disabled).mat-warn .mat-select-underline,.mat-select:not(:focus).ng-invalid.ng-touched:not(.mat-select-disabled) .mat-select-underline{background-color:#f44336}.mat-sidenav-container{background-color:#fafafa;color:rgba(0,0,0,.87)}.mat-sidenav{color:rgba(0,0,0,.87)}.mat-sidenav,.mat-sidenav.mat-sidenav-push{background-color:#fff}.mat-sidenav-backdrop.mat-sidenav-shown{background-color:rgba(0,0,0,.6)}.mat-slide-toggle.mat-checked:not(.mat-disabled) .mat-slide-toggle-thumb{background-color:#e91e63}.mat-slide-toggle.mat-checked:not(.mat-disabled) .mat-slide-toggle-bar{background-color:rgba(233,30,99,.5)}.mat-slide-toggle:not(.mat-checked) .mat-ripple-element{background-color:rgba(0,0,0,.06)}.mat-slide-toggle .mat-ripple-element{background-color:rgba(233,30,99,.12)}.mat-slide-toggle.mat-primary.mat-checked:not(.mat-disabled) .mat-slide-toggle-thumb{background-color:#e91e63}.mat-slide-toggle.mat-primary.mat-checked:not(.mat-disabled) .mat-slide-toggle-bar{background-color:rgba(233,30,99,.5)}.mat-slide-toggle.mat-primary:not(.mat-checked) .mat-ripple-element{background-color:rgba(0,0,0,.06)}.mat-slide-toggle.mat-primary .mat-ripple-element{background-color:rgba(233,30,99,.12)}.mat-slide-toggle.mat-warn.mat-checked:not(.mat-disabled) .mat-slide-toggle-thumb{background-color:#f44336}.mat-slide-toggle.mat-warn.mat-checked:not(.mat-disabled) .mat-slide-toggle-bar{background-color:rgba(244,67,54,.5)}.mat-slide-toggle.mat-warn:not(.mat-checked) .mat-ripple-element{background-color:rgba(0,0,0,.06)}.mat-slide-toggle.mat-warn .mat-ripple-element{background-color:rgba(244,67,54,.12)}.mat-disabled .mat-slide-toggle-thumb{background-color:#bdbdbd}.mat-disabled .mat-slide-toggle-bar{background-color:rgba(0,0,0,.1)}.mat-slide-toggle-thumb{background-color:#fafafa}.mat-slide-toggle-bar{background-color:rgba(0,0,0,.38)}.mat-slider-track-background{background-color:rgba(0,0,0,.26)}.mat-primary .mat-slider-thumb,.mat-primary .mat-slider-thumb-label,.mat-primary .mat-slider-track-fill{background-color:#e91e63}.mat-primary .mat-slider-thumb-label-text{color:#fff}.mat-accent .mat-slider-thumb,.mat-accent .mat-slider-thumb-label,.mat-accent .mat-slider-track-fill{background-color:#ad1457}.mat-accent .mat-slider-thumb-label-text{color:hsla(0,0%,100%,.87)}.mat-warn .mat-slider-thumb,.mat-warn .mat-slider-thumb-label,.mat-warn .mat-slider-track-fill{background-color:#f44336}.mat-warn .mat-slider-thumb-label-text{color:#fff}.mat-slider-focus-ring{background-color:rgba(173,20,87,.2)}.cdk-focused .mat-slider-track-background,.mat-slider:hover .mat-slider-track-background{background-color:rgba(0,0,0,.38)}.mat-slider-disabled .mat-slider-thumb,.mat-slider-disabled .mat-slider-track-background,.mat-slider-disabled .mat-slider-track-fill,.mat-slider-disabled:hover .mat-slider-track-background{background-color:rgba(0,0,0,.26)}.mat-slider-min-value .mat-slider-focus-ring{background-color:rgba(0,0,0,.12)}.mat-slider-min-value.mat-slider-thumb-label-showing .mat-slider-thumb,.mat-slider-min-value.mat-slider-thumb-label-showing .mat-slider-thumb-label{background-color:#000}.mat-slider-min-value.mat-slider-thumb-label-showing.cdk-focused .mat-slider-thumb,.mat-slider-min-value.mat-slider-thumb-label-showing.cdk-focused .mat-slider-thumb-label{background-color:rgba(0,0,0,.26)}.mat-slider-min-value:not(.mat-slider-thumb-label-showing) .mat-slider-thumb{border-color:rgba(0,0,0,.26);background-color:transparent}.mat-slider-min-value:not(.mat-slider-thumb-label-showing).cdk-focused .mat-slider-thumb,.mat-slider-min-value:not(.mat-slider-thumb-label-showing):hover .mat-slider-thumb{border-color:rgba(0,0,0,.38)}.mat-slider-min-value:not(.mat-slider-thumb-label-showing).cdk-focused.mat-slider-disabled .mat-slider-thumb,.mat-slider-min-value:not(.mat-slider-thumb-label-showing):hover.mat-slider-disabled .mat-slider-thumb{border-color:rgba(0,0,0,.26)}.mat-slider-has-ticks .mat-slider-wrapper:after{border-color:rgba(0,0,0,.7)}.mat-slider-horizontal .mat-slider-ticks{background-image:repeating-linear-gradient(90deg,rgba(0,0,0,.7),rgba(0,0,0,.7) 2px,transparent 0,transparent);background-image:-moz-repeating-linear-gradient(.0001deg,rgba(0,0,0,.7),rgba(0,0,0,.7) 2px,transparent 0,transparent)}.mat-slider-vertical .mat-slider-ticks{background-image:repeating-linear-gradient(180deg,rgba(0,0,0,.7),rgba(0,0,0,.7) 2px,transparent 0,transparent)}.mat-tab-header,.mat-tab-nav-bar{border-bottom:1px solid rgba(0,0,0,.12)}.mat-tab-group-inverted-header .mat-tab-header,.mat-tab-group-inverted-header .mat-tab-nav-bar{border-top:1px solid rgba(0,0,0,.12);border-bottom:none}.mat-tab-label:focus{background-color:rgba(248,187,208,.3)}.mat-ink-bar{background-color:#e91e63}.mat-tab-label,.mat-tab-link{color:rgba(0,0,0,.87)}.mat-tab-label.mat-tab-disabled,.mat-tab-link.mat-tab-disabled{color:rgba(0,0,0,.38)}.mat-toolbar{background:#f5f5f5;color:rgba(0,0,0,.87)}.mat-toolbar.mat-primary{background:#e91e63;color:#fff}.mat-toolbar.mat-accent{background:#ad1457;color:hsla(0,0%,100%,.87)}.mat-toolbar.mat-warn{background:#f44336;color:#fff}.mat-tooltip{background:rgba(97,97,97,.9)}
--------------------------------------------------------------------------------
/docs/sw-register.c12a0e1d4fd37a7ce413.bundle.js:
--------------------------------------------------------------------------------
1 | webpackJsonp([5],{0:function(r,e,o){r.exports=o("3WLI")},"3WLI":function(r,e){"serviceWorker"in navigator&&navigator.serviceWorker.register("worker-basic.min.js").catch(function(r){console.error("Error registering service worker:",r)})}},[0]);
--------------------------------------------------------------------------------
/e2e/app.e2e-spec.ts:
--------------------------------------------------------------------------------
1 | import { EAppPage } from './app.po';
2 |
3 | describe('e-app App', () => {
4 | let page: EAppPage;
5 |
6 | beforeEach(() => {
7 | page = new EAppPage();
8 | });
9 |
10 | it('should display welcome message', done => {
11 | page.navigateTo();
12 | page.getParagraphText()
13 | .then(msg => expect(msg).toEqual('Welcome to app!!'))
14 | .then(done, done.fail);
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/e2e/app.po.ts:
--------------------------------------------------------------------------------
1 | import { browser, by, element } from 'protractor';
2 |
3 | export class EAppPage {
4 | navigateTo() {
5 | return browser.get('/');
6 | }
7 |
8 | getParagraphText() {
9 | return element(by.css('app-root h1')).getText();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/e2e/tsconfig.e2e.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../out-tsc/e2e",
5 | "module": "commonjs",
6 | "target": "es5",
7 | "types": [
8 | "jasmine",
9 | "node"
10 | ]
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration file, see link for more information
2 | // https://karma-runner.github.io/0.13/config/configuration-file.html
3 |
4 | module.exports = function (config) {
5 | config.set({
6 | basePath: '',
7 | frameworks: ['jasmine', '@angular/cli'],
8 | plugins: [
9 | require('karma-jasmine'),
10 | require('karma-chrome-launcher'),
11 | require('karma-jasmine-html-reporter'),
12 | require('karma-coverage-istanbul-reporter'),
13 | require('@angular/cli/plugins/karma')
14 | ],
15 | client:{
16 | clearContext: false // leave Jasmine Spec Runner output visible in browser
17 | },
18 | coverageIstanbulReporter: {
19 | reports: [ 'html', 'lcovonly' ],
20 | fixWebpackSourcePaths: true
21 | },
22 | angularCli: {
23 | environment: 'dev'
24 | },
25 | reporters: ['progress', 'kjhtml'],
26 | port: 9876,
27 | colors: true,
28 | logLevel: config.LOG_INFO,
29 | autoWatch: true,
30 | browsers: ['Chrome'],
31 | singleRun: false
32 | });
33 | };
34 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-pwa-firebase-ecommerce",
3 | "version": "0.0.0",
4 | "license": "MIT",
5 | "scripts": {
6 | "ng": "ng",
7 | "start": "ng serve",
8 | "build": "ng build",
9 | "test": "ng test",
10 | "lint": "ng lint",
11 | "e2e": "ng e2e"
12 | },
13 | "private": true,
14 | "dependencies": {
15 | "@angular/animations": "^4.0.0",
16 | "@angular/common": "^4.0.0",
17 | "@angular/compiler": "^4.0.0",
18 | "@angular/core": "^4.0.0",
19 | "@angular/forms": "^4.0.0",
20 | "@angular/http": "^4.0.0",
21 | "@angular/material": "^2.0.0-beta.7",
22 | "@angular/platform-browser": "^4.0.0",
23 | "@angular/platform-browser-dynamic": "^4.0.0",
24 | "@angular/router": "^4.0.0",
25 | "core-js": "^2.4.1",
26 | "hammerjs": "^2.0.8",
27 | "rxjs": "^5.1.0",
28 | "zone.js": "^0.8.4"
29 | },
30 | "devDependencies": {
31 | "@angular/cli": "1.1.0",
32 | "@angular/compiler-cli": "^4.2.5",
33 | "@angular/language-service": "^4.0.0",
34 | "@angular/service-worker": "^1.0.0-beta.16",
35 | "@types/jasmine": "2.5.45",
36 | "@types/node": "~6.0.60",
37 | "codelyzer": "~3.0.1",
38 | "jasmine-core": "~2.6.2",
39 | "jasmine-spec-reporter": "~4.1.0",
40 | "karma": "~1.7.0",
41 | "karma-chrome-launcher": "~2.1.1",
42 | "karma-cli": "~1.0.1",
43 | "karma-coverage-istanbul-reporter": "^1.2.1",
44 | "karma-jasmine": "~1.1.0",
45 | "karma-jasmine-html-reporter": "^0.2.2",
46 | "protractor": "~5.1.2",
47 | "ts-node": "~3.0.4",
48 | "tslint": "~5.3.2",
49 | "typescript": "~2.3.4"
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/protractor.conf.js:
--------------------------------------------------------------------------------
1 | // Protractor configuration file, see link for more information
2 | // https://github.com/angular/protractor/blob/master/lib/config.ts
3 |
4 | const { SpecReporter } = require('jasmine-spec-reporter');
5 |
6 | exports.config = {
7 | allScriptsTimeout: 11000,
8 | specs: [
9 | './e2e/**/*.e2e-spec.ts'
10 | ],
11 | capabilities: {
12 | 'browserName': 'chrome'
13 | },
14 | directConnect: true,
15 | baseUrl: 'http://localhost:4200/',
16 | framework: 'jasmine',
17 | jasmineNodeOpts: {
18 | showColors: true,
19 | defaultTimeoutInterval: 30000,
20 | print: function() {}
21 | },
22 | onPrepare() {
23 | require('ts-node').register({
24 | project: 'e2e/tsconfig.e2e.json'
25 | });
26 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
27 | }
28 | };
29 |
--------------------------------------------------------------------------------
/src/apfem-theme.scss:
--------------------------------------------------------------------------------
1 | @import '~@angular/material/theming';
2 | // Plus imports for other components in your app.
3 |
4 | // Include the common styles for Angular Material. We include this here so that you only
5 | // have to load a single css file for Angular Material in your app.
6 | // Be sure that you only ever include this mixin once!
7 | @include mat-core();
8 |
9 | // Define the palettes for your theme using the Material Design palettes available in palette.scss
10 | // (imported above). For each palette, you can optionally specify a default, lighter, and darker
11 | // hue.
12 | $apfem-app-primary: mat-palette($mat-pink);
13 | $apfem-app-accent: mat-palette($mat-pink, 800);
14 |
15 | // The warn palette is optional (defaults to red).
16 | $apfem-app-warn: mat-palette($mat-red);
17 |
18 | // Create the theme object (a Sass map containing all of the palettes).
19 | $apfem-app-theme: mat-light-theme($apfem-app-primary, $apfem-app-accent, $apfem-app-warn);
20 |
21 | // Include theme styles for core and each component used in your app.
22 | // Alternatively, you can import and @include the theme mixins for each component
23 | // that you are using.
24 | @include angular-material-theme($apfem-app-theme);
--------------------------------------------------------------------------------
/src/app/app.component.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daviskoko/angular-firebase-ecommerce/8c72f065d7f2fe166fbbaf2638872f43ad2a246a/src/app/app.component.css
--------------------------------------------------------------------------------
/src/app/app.component.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/app/app.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed, async } from '@angular/core/testing';
2 |
3 | import { AppComponent } from './app.component';
4 |
5 | describe('AppComponent', () => {
6 | beforeEach(async(() => {
7 | TestBed.configureTestingModule({
8 | declarations: [
9 | AppComponent
10 | ],
11 | }).compileComponents();
12 | }));
13 |
14 | it('should create the app', async(() => {
15 | const fixture = TestBed.createComponent(AppComponent);
16 | const app = fixture.debugElement.componentInstance;
17 | expect(app).toBeTruthy();
18 | }));
19 |
20 | it(`should have as title 'app'`, async(() => {
21 | const fixture = TestBed.createComponent(AppComponent);
22 | const app = fixture.debugElement.componentInstance;
23 | expect(app.title).toEqual('app');
24 | }));
25 |
26 | it('should render title in a h1 tag', async(() => {
27 | const fixture = TestBed.createComponent(AppComponent);
28 | fixture.detectChanges();
29 | const compiled = fixture.debugElement.nativeElement;
30 | expect(compiled.querySelector('h1').textContent).toContain('Welcome to app!!');
31 | }));
32 | });
33 |
--------------------------------------------------------------------------------
/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-root',
5 | templateUrl: './app.component.html',
6 | styleUrls: ['./app.component.css']
7 | })
8 | export class AppComponent {
9 | }
10 |
--------------------------------------------------------------------------------
/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { FormsModule } from '@angular/forms';
3 | import { HttpModule } from '@angular/http';
4 | import { MaterialModule } from '@angular/material';
5 | import { BrowserModule } from '@angular/platform-browser';
6 | import { CommonModule, LocationStrategy, PathLocationStrategy } from "@angular/common";
7 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
8 | import 'hammerjs';
9 |
10 | import { AppRouting } from './app.routing';
11 | import { AppComponent } from './app.component';
12 | import { DefaultLayoutComponent, SimpleLayoutComponent } from './layouts';
13 | import { HomepageComponent } from './homepage.component';
14 | import { CarouselModule } from './shared/carousel.module';
15 | import {
16 | SideNavComponent,
17 | MainNavComponent,
18 | FooterComponent,
19 | CartCounterComponent
20 | } from './shared';
21 | import { ItemService } from "app/items/item.service";
22 | import { CartService } from "app/cart/cart.service";
23 |
24 | @NgModule({
25 | declarations: [
26 | AppComponent,
27 | DefaultLayoutComponent,
28 | SimpleLayoutComponent,
29 | SideNavComponent,
30 | MainNavComponent,
31 | FooterComponent,
32 | CartCounterComponent,
33 | HomepageComponent
34 | ],
35 | imports: [
36 | BrowserModule,
37 | FormsModule,
38 | HttpModule,
39 | AppRouting,
40 | MaterialModule,
41 | BrowserAnimationsModule,
42 | CarouselModule
43 | ],
44 | providers: [
45 | ItemService,
46 | CartService,
47 | {
48 | provide: LocationStrategy,
49 | useClass: PathLocationStrategy
50 | }
51 | ],
52 | bootstrap: [AppComponent]
53 | })
54 | export class AppModule { }
55 |
--------------------------------------------------------------------------------
/src/app/app.routing.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { Routes, RouterModule } from '@angular/router';
3 |
4 | // Layouts
5 | import { DefaultLayoutComponent } from './layouts/default-layout.component';
6 | import { SimpleLayoutComponent } from './layouts/simple-layout.component';
7 | import { HomepageComponent } from 'app/homepage.component';
8 |
9 | export const routes: Routes = [
10 | {
11 | path: '',
12 | component: HomepageComponent
13 | },
14 | {
15 | path: 'items',
16 | component: DefaultLayoutComponent,
17 | children: [
18 | {
19 | path: '',
20 | loadChildren: 'app/items/items.module#ItemsModule'
21 | }
22 | ]
23 | },
24 | {
25 | path: 'my-cart',
26 | component: DefaultLayoutComponent,
27 | children: [
28 | {
29 | path: '',
30 | loadChildren: 'app/cart/cart.module#CartModule'
31 | }
32 | ]
33 | }
34 | ];
35 |
36 | @NgModule({
37 | imports: [ RouterModule.forRoot(routes) ],
38 | exports: [ RouterModule ]
39 | })
40 | export class AppRouting {}
41 |
--------------------------------------------------------------------------------
/src/app/cart/cart-item.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { CartItemComponent } from './cart-item.component';
4 |
5 | describe('CartItemComponent', () => {
6 | let component: CartItemComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async(() => {
10 | TestBed.configureTestingModule({
11 | declarations: [ CartItemComponent ]
12 | })
13 | .compileComponents();
14 | }));
15 |
16 | beforeEach(() => {
17 | fixture = TestBed.createComponent(CartItemComponent);
18 | component = fixture.componentInstance;
19 | fixture.detectChanges();
20 | });
21 |
22 | it('should be created', () => {
23 | expect(component).toBeTruthy();
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/src/app/cart/cart-item.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit, Input } from '@angular/core';
2 | import { FormGroup, FormControl, Validators } from '@angular/forms';
3 |
4 | import { Item } from 'app/items';
5 |
6 | @Component({
7 | selector: 'apfem-cart-item',
8 | template: `
9 |
10 |
16 |
17 |
{{cartItem.val.item.name}}
18 |
{{cartItem.val.item.price | currency:'USD':true}}
19 | {{cartItem.val.item.old_price | currency:'USD':true}}
20 |
36 |
37 |
38 |
39 | `,
40 | styles: ['.cart-wrapper{border:1px solid #eee; background-color:#fff; border-radius:4px;}']
41 | })
42 | export class CartItemComponent implements OnInit {
43 |
44 | @Input() cartItem;
45 | updateCartForm: FormGroup;
46 | numbers = [
47 | {value: 1, display: 'One'},
48 | {value: 2, display: 'Two'},
49 | {value: 3, display: 'Three'},
50 | {value: 4, display: 'Four'},
51 | {value: 5, display: 'Five'}
52 | ];
53 |
54 | constructor() {
55 | this.updateCartForm = new FormGroup({
56 | 'item': new FormControl('', Validators.required),
57 | 'quantity': new FormControl('', Validators.required)
58 | });
59 | }
60 |
61 | onUpdateCart() {
62 | console.log(this.updateCartForm.value);
63 | }
64 |
65 | ngOnInit() {
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/src/app/cart/cart-routing.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { Routes, RouterModule } from '@angular/router';
3 |
4 | import {
5 | CartComponent
6 | } from './index';
7 |
8 | const routes: Routes = [
9 | {
10 | path: '',
11 | component: CartComponent
12 | }
13 | ];
14 |
15 | @NgModule({
16 | imports: [RouterModule.forChild(routes)],
17 | exports: [RouterModule]
18 | })
19 | export class CartRoutingModule {}
20 |
--------------------------------------------------------------------------------
/src/app/cart/cart.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
My Cart
5 |
You have {{cart.length}} items in your basket
6 |
10 |
11 |
= 1" class="row center-xs">
12 |
15 |
18 |
19 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/app/cart/cart.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { CartComponent } from './cart.component';
4 |
5 | describe('CartComponent', () => {
6 | let component: CartComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async(() => {
10 | TestBed.configureTestingModule({
11 | declarations: [ CartComponent ]
12 | })
13 | .compileComponents();
14 | }));
15 |
16 | beforeEach(() => {
17 | fixture = TestBed.createComponent(CartComponent);
18 | component = fixture.componentInstance;
19 | fixture.detectChanges();
20 | });
21 |
22 | it('should be created', () => {
23 | expect(component).toBeTruthy();
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/src/app/cart/cart.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 |
3 | import { CartService, Cart } from "./index";
4 |
5 | @Component({
6 | selector: 'apfem-cart',
7 | templateUrl: './cart.component.html',
8 | styles: ['.cart{min-height:500px;}']
9 | })
10 | export class CartComponent implements OnInit {
11 |
12 | cart: Cart[] = [];
13 |
14 | constructor(
15 | private cartService: CartService
16 | ) { }
17 |
18 | ngOnInit() {
19 | this.cart = this.cartService.getCart();
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/src/app/cart/cart.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { MaterialModule } from '@angular/material';
4 | import { ReactiveFormsModule } from '@angular/forms';
5 |
6 | import { CartRoutingModule } from "app/cart/cart-routing.module";
7 | import { CartComponent } from './cart.component';
8 | import { CartItemComponent } from './cart-item.component';
9 |
10 | @NgModule({
11 | imports: [
12 | CommonModule,
13 | CartRoutingModule,
14 | MaterialModule,
15 | ReactiveFormsModule
16 | ],
17 | declarations: [CartComponent, CartItemComponent]
18 | })
19 | export class CartModule { }
20 |
--------------------------------------------------------------------------------
/src/app/cart/cart.service.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed, inject } from '@angular/core/testing';
2 |
3 | import { CartService } from './cart.service';
4 |
5 | describe('CartService', () => {
6 | beforeEach(() => {
7 | TestBed.configureTestingModule({
8 | providers: [CartService]
9 | });
10 | });
11 |
12 | it('should be created', inject([CartService], (service: CartService) => {
13 | expect(service).toBeTruthy();
14 | }));
15 | });
16 |
--------------------------------------------------------------------------------
/src/app/cart/cart.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 |
3 | import { Cart } from "./index";
4 |
5 | @Injectable()
6 | export class CartService {
7 |
8 | private cart: Cart[] = [];
9 |
10 | constructor() { }
11 |
12 | private findLocalStorageItems(query) {
13 | let i, results = [];
14 | for (i in localStorage) {
15 | if (localStorage.hasOwnProperty(i)) {
16 | if (i.match(query) || (!query && typeof i === 'string')) {
17 | let value = JSON.parse(localStorage.getItem(i));
18 | results.push({key:i,val:value});
19 | }
20 | }
21 | }
22 | return results;
23 | }
24 |
25 | // Get user cart
26 | getCart(){
27 | return this.cart = this.getCartFromLocalStorage();
28 | }
29 |
30 | // Extract values that has the 'cart-' key from the localStorage
31 | getCartFromLocalStorage(){
32 | return this.findLocalStorageItems('cart-');
33 | }
34 |
35 | // Add item to cart(localStorage)
36 | addItemToCart(formValues: Cart) {
37 | this.cart.push(formValues);
38 | }
39 |
40 | // Remove item from cart and localStorage
41 | removeItemFromCart(cart: Cart) {
42 | localStorage.removeItem('cart-' + cart.item.slug);
43 | }
44 |
45 | // Remove all items in the cart
46 | clear() {
47 | return this.findLocalStorageItems('item-').splice(1)
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/src/app/cart/cart.ts:
--------------------------------------------------------------------------------
1 | import { Item } from '../items';
2 |
3 | export class Cart {
4 | item: Item;
5 | size: number;
6 | color: number;
7 | quantity: number;
8 | }
--------------------------------------------------------------------------------
/src/app/cart/index.ts:
--------------------------------------------------------------------------------
1 | export { CartService } from './cart.service';
2 | export { Cart } from './cart';
3 | export { CartComponent } from './cart.component';
--------------------------------------------------------------------------------
/src/app/homepage.component.css:
--------------------------------------------------------------------------------
1 | @media only screen and (min-width: 768px) {
2 | .menu {
3 | display: none;
4 | }
5 | }
6 |
7 | @media only screen and (max-width: 768px) {
8 | .back-arrow {
9 | display: none;
10 | }
11 | }
--------------------------------------------------------------------------------
/src/app/homepage.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
9 |
10 |
11 | APFEM SHOP
12 |
13 |
14 |
15 |
16 |
17 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/src/app/homepage.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { Response } from '@angular/http';
3 |
4 | import { ItemService, Item } from './items';
5 |
6 | @Component({
7 | selector: 'apfem-homepage',
8 | templateUrl: './homepage.component.html',
9 | styleUrls: ['./homepage.component.css']
10 | })
11 | export class HomepageComponent implements OnInit {
12 |
13 | delay = 5000;
14 | loop = false;
15 | loading = false;
16 | items: Item[] = [];
17 | slides: Array = [
18 | {link: '#', color: 'grey'},
19 | {link: '#', color: 'purple'},
20 | {link: '#', color: 'yellow'},
21 | {link: '#', color: 'orange'}
22 | ];
23 |
24 | constructor(
25 | private itemService: ItemService
26 | ) { }
27 |
28 | // Simulate a post
29 | postItems() {
30 | this.itemService.storeItem().subscribe(
31 | (data: Response) => console.log(data.statusText)
32 | )
33 | }
34 |
35 | getItems() {
36 | this.loading = true;
37 | this.itemService.getItems().subscribe(
38 | data => {
39 | this.items = data,
40 | this.loading = false
41 | }
42 | );
43 | }
44 |
45 | ngOnInit() {
46 | this.getItems();
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/app/items/index.ts:
--------------------------------------------------------------------------------
1 | export { ItemService } from './item.service';
2 | export { Item, Image, Category } from './item';
3 | export { ItemDetailsComponent } from './item-details.component';
4 | export { ItemListComponent } from './item-list.component';
5 | export { ItemComponent } from './item.component';
6 | export { ItemByCategoryComponent } from './item-by-category.component';
--------------------------------------------------------------------------------
/src/app/items/item-by-category.component.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daviskoko/angular-firebase-ecommerce/8c72f065d7f2fe166fbbaf2638872f43ad2a246a/src/app/items/item-by-category.component.css
--------------------------------------------------------------------------------
/src/app/items/item-by-category.component.html:
--------------------------------------------------------------------------------
1 |
2 | item-by-category works!
3 |
4 |
--------------------------------------------------------------------------------
/src/app/items/item-by-category.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { ItemByCategoryComponent } from './item-by-category.component';
4 |
5 | describe('ItemByCategoryComponent', () => {
6 | let component: ItemByCategoryComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async(() => {
10 | TestBed.configureTestingModule({
11 | declarations: [ ItemByCategoryComponent ]
12 | })
13 | .compileComponents();
14 | }));
15 |
16 | beforeEach(() => {
17 | fixture = TestBed.createComponent(ItemByCategoryComponent);
18 | component = fixture.componentInstance;
19 | fixture.detectChanges();
20 | });
21 |
22 | it('should be created', () => {
23 | expect(component).toBeTruthy();
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/src/app/items/item-by-category.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'apfem-item-by-category',
5 | templateUrl: './item-by-category.component.html',
6 | styleUrls: ['./item-by-category.component.css']
7 | })
8 | export class ItemByCategoryComponent implements OnInit {
9 |
10 | constructor() { }
11 |
12 | ngOnInit() {
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/src/app/items/item-details.component.css:
--------------------------------------------------------------------------------
1 | .img {
2 | padding: 8px;
3 | /*border: 1px solid #eee;*/
4 | border-radius: 4px;
5 | }
--------------------------------------------------------------------------------
/src/app/items/item-details.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
{{item.name}}
19 |
{{item.price | currency:USD:true}}
20 |
{{item.old_price | currency:USD:true}}
21 |
Availability
{{item.availability}}
22 |
34 |
35 |
36 |
37 |
38 |
Description:
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/src/app/items/item-details.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { ItemDetailsComponent } from './item-details.component';
4 |
5 | describe('ItemDetailsComponent', () => {
6 | let component: ItemDetailsComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async(() => {
10 | TestBed.configureTestingModule({
11 | declarations: [ ItemDetailsComponent ]
12 | })
13 | .compileComponents();
14 | }));
15 |
16 | beforeEach(() => {
17 | fixture = TestBed.createComponent(ItemDetailsComponent);
18 | component = fixture.componentInstance;
19 | fixture.detectChanges();
20 | });
21 |
22 | it('should be created', () => {
23 | expect(component).toBeTruthy();
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/src/app/items/item-details.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnDestroy, OnInit } from '@angular/core';
2 | import { Router, ActivatedRoute } from '@angular/router';
3 | import { MdSnackBar } from '@angular/material';
4 | import { FormGroup, FormControl, Validators } from '@angular/forms';
5 |
6 | import { ItemService, Item } from './index';
7 | import { CartService } from '../cart/cart.service';
8 |
9 | @Component({
10 | selector: 'apfem-item-details',
11 | templateUrl: './item-details.component.html',
12 | styleUrls: ['./item-details.component.css']
13 | })
14 | export class ItemDetailsComponent implements OnInit {
15 |
16 | loading = false;
17 | delay = 5000;
18 | loop = false;
19 | item: Item;
20 | cartForm: FormGroup;
21 | itemIndex: any;
22 | numbers = [
23 | {value: 1, display: 'One'},
24 | {value: 2, display: 'Two'},
25 | {value: 3, display: 'Three'},
26 | {value: 4, display: 'Four'},
27 | {value: 5, display: 'Five'}
28 | ];
29 |
30 | constructor(
31 | private route: ActivatedRoute,
32 | private itemService: ItemService,
33 | private snackBar: MdSnackBar,
34 | private cartService: CartService
35 | ) {
36 | this.cartForm = new FormGroup({
37 | 'item': new FormControl('', Validators.required),
38 | 'quantity': new FormControl('', Validators.required)
39 | });
40 | }
41 |
42 | /**
43 | * Get an item from the items array using the slug parameter
44 | */
45 | getItem() {
46 | this.route.params.subscribe(
47 | (params: any) => {
48 | this.itemIndex = params['slug'];
49 | this.item = this.itemService.getItem(this.itemIndex);
50 | }
51 | );
52 | }
53 |
54 | /**
55 | * Add item to cart(users browser - localStorage)
56 | */
57 | onAddToCart() {
58 | this.loading = true;
59 | if (localStorage.getItem('cart-' + this.item.slug)) {
60 | this.snackBar.open('Already in your cart!', 'Ok', {
61 | duration: 5000,
62 | }),
63 | this.loading = false;
64 | } else {
65 | this.cartService.addItemToCart(this.cartForm.value);
66 | localStorage.setItem('cart-' + this.item.slug, JSON.stringify(this.cartForm.value));
67 | this.snackBar.open('Successfully added to cart!', 'Dismiss', {
68 | duration: 5000,
69 | });
70 | }
71 | }
72 |
73 | ngOnInit() {
74 | this.getItem();
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/app/items/item-list.component.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daviskoko/angular-firebase-ecommerce/8c72f065d7f2fe166fbbaf2638872f43ad2a246a/src/app/items/item-list.component.css
--------------------------------------------------------------------------------
/src/app/items/item-list.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
List of items
5 |
6 |
14 |
15 |
--------------------------------------------------------------------------------
/src/app/items/item-list.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { ItemListComponent } from './item-list.component';
4 |
5 | describe('ItemListComponent', () => {
6 | let component: ItemListComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async(() => {
10 | TestBed.configureTestingModule({
11 | declarations: [ ItemListComponent ]
12 | })
13 | .compileComponents();
14 | }));
15 |
16 | beforeEach(() => {
17 | fixture = TestBed.createComponent(ItemListComponent);
18 | component = fixture.componentInstance;
19 | fixture.detectChanges();
20 | });
21 |
22 | it('should be created', () => {
23 | expect(component).toBeTruthy();
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/src/app/items/item-list.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 |
3 | import { ItemService, Item } from './index';
4 |
5 | @Component({
6 | selector: 'apfem-item-list',
7 | templateUrl: './item-list.component.html',
8 | styleUrls: ['./item-list.component.css']
9 | })
10 | export class ItemListComponent implements OnInit {
11 |
12 | loading = false;
13 | items: Item[] = [];
14 |
15 | constructor(
16 | private itemService: ItemService
17 | ) { }
18 |
19 | /**
20 | * Get the items from the service
21 | */
22 | getItems() {
23 | this.loading = true;
24 | this.itemService.getItems().subscribe(
25 | data => {
26 | this.items = data,
27 | this.loading = false
28 | }
29 | );
30 | }
31 |
32 | ngOnInit() {
33 | this.getItems();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/app/items/item-routing.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { Routes, RouterModule } from '@angular/router';
3 |
4 | import {
5 | ItemDetailsComponent,
6 | ItemByCategoryComponent,
7 | ItemListComponent
8 | } from './index';
9 |
10 | const routes: Routes = [
11 | {
12 | path: '',
13 | component: ItemListComponent
14 | },
15 | {
16 | path: ':slug',
17 | component: ItemDetailsComponent
18 | },
19 | {
20 | path: ':slug/items',
21 | component: ItemByCategoryComponent
22 | }
23 | ];
24 |
25 | @NgModule({
26 | imports: [RouterModule.forChild(routes)],
27 | exports: [RouterModule]
28 | })
29 | export class ItemRoutingModule {}
30 |
--------------------------------------------------------------------------------
/src/app/items/item.component.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daviskoko/angular-firebase-ecommerce/8c72f065d7f2fe166fbbaf2638872f43ad2a246a/src/app/items/item.component.css
--------------------------------------------------------------------------------
/src/app/items/item.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 | {{ item.name }}
11 | {{ item.price | currency:'USD':true }}
12 | {{item.old_price | currency:USD:true}}
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/app/items/item.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { ItemComponent } from './item.component';
4 |
5 | describe('ItemComponent', () => {
6 | let component: ItemComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async(() => {
10 | TestBed.configureTestingModule({
11 | declarations: [ ItemComponent ]
12 | })
13 | .compileComponents();
14 | }));
15 |
16 | beforeEach(() => {
17 | fixture = TestBed.createComponent(ItemComponent);
18 | component = fixture.componentInstance;
19 | fixture.detectChanges();
20 | });
21 |
22 | it('should be created', () => {
23 | expect(component).toBeTruthy();
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/src/app/items/item.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit, Input } from '@angular/core';
2 |
3 | import { Item } from './index';
4 |
5 | @Component({
6 | selector: 'apfem-item',
7 | templateUrl: './item.component.html',
8 | styleUrls: ['./item.component.css']
9 | })
10 | export class ItemComponent implements OnInit {
11 |
12 | @Input() item: Item;
13 | @Input() selectedItem: number;
14 |
15 | constructor() { }
16 |
17 | ngOnInit() {
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/src/app/items/item.service.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed, inject } from '@angular/core/testing';
2 |
3 | import { ItemService } from './item.service';
4 |
5 | describe('ItemService', () => {
6 | beforeEach(() => {
7 | TestBed.configureTestingModule({
8 | providers: [ItemService]
9 | });
10 | });
11 |
12 | it('should be created', inject([ItemService], (service: ItemService) => {
13 | expect(service).toBeTruthy();
14 | }));
15 | });
16 |
--------------------------------------------------------------------------------
/src/app/items/item.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { Headers, Http, Response } from '@angular/http';
3 | import { Observable } from 'rxjs/Rx';
4 |
5 | import { Item, Image, Category } from './index';
6 |
7 | @Injectable()
8 | export class ItemService {
9 |
10 | private header = new Headers({'Content-Type': 'application/json'});
11 | private firbaseApi = 'https://apfem-78c34.firebaseio.com/';
12 |
13 | // Item sample data
14 | private items: Item[] = [
15 | new Item('angular-t-shirt', 'Angular T-Shirt', new Category('t-shirt', 'T-Shirts'), 120, 135, 'In Stock', 'Lorem ipsum dolor sit amet, no agam populo apeirian pri, ea eirmod scaevola voluptatibus per. No est maluisset sadipscing, duo soluta dignissim dissentiet ei, malis possim posidonium ad has. Dico error utamur an est, ex tantas expetendis sit. Convenire disputando repudiandae nam no, laudem malorum quaeque sit id.',
16 | [
17 | new Image('http://devstickers.com/assets/img/pro/tee/8ki7_mhoodiez.png'),
18 | new Image('http://devstickers.com/assets/img/pro/tee/lrj4_mens.png')
19 | ]),
20 | new Item('gulp-sass-cup', 'Gulp & Sass Cup', new Category('cup', 'Cups'), 90, 105, 'Pre-Order', 'Lorem ipsum dolor sit amet, no agam populo apeirian pri, ea eirmod scaevola voluptatibus per. No est maluisset sadipscing, duo soluta dignissim dissentiet ei, malis possim posidonium ad has. Dico error utamur an est, ex tantas expetendis sit. Convenire disputando repudiandae nam no, laudem malorum quaeque sit id.',
21 | [
22 | new Image('http://www.joel-chrabie.com/res/js/gulpsass.png'),
23 | new Image('http://vesparny.github.io/angular-kickstart/assets/images/gulp-logo.png')
24 | ]),
25 | new Item('google-cup', 'Google Cup', new Category('cup', 'Cups'), 96, 117, 'In Stock', 'Lorem ipsum dolor sit amet, no agam populo apeirian pri, ea eirmod scaevola voluptatibus per. No est maluisset sadipscing, duo soluta dignissim dissentiet ei, malis possim posidonium ad has. Dico error utamur an est, ex tantas expetendis sit. Convenire disputando repudiandae nam no, laudem malorum quaeque sit id.',
26 | [
27 | new Image('https://images-na.ssl-images-amazon.com/images/I/71aEJmSmIYL._SX355_.jpg'),
28 | new Image('http://www.mypeyronies.com/image-files/hourglass-penis-indentations.jpg')
29 | ]),
30 | new Item('female-t-shirts', 'Female T-Shirts(Pink)', new Category('t-shirt', 'T-Shirts'), 90, 108, 'Pre-Order', 'Lorem ipsum dolor sit amet, no agam populo apeirian pri, ea eirmod scaevola voluptatibus per. No est maluisset sadipscing, duo soluta dignissim dissentiet ei, malis possim posidonium ad has. Dico error utamur an est, ex tantas expetendis sit. Convenire disputando repudiandae nam no, laudem malorum quaeque sit id.',
31 | [
32 | new Image('https://www.mulboo.com.au/wp-content/uploads/2013/04/Ladies-Pink-T-shirt.png'),
33 | new Image('https://shop.googlemerchandisestore.com/store/20160512512/assets/items/images/GGOEGAAX0339.jpg')
34 | ]),
35 | new Item('female-google-t-shirts-black', 'White Female T-Shirts', new Category('t-shirt', 'T-Shirts'), 90, 108, 'Pre-Order', 'Lorem ipsum dolor sit amet, no agam populo apeirian pri, ea eirmod scaevola voluptatibus per. No est maluisset sadipscing, duo soluta dignissim dissentiet ei, malis possim posidonium ad has. Dico error utamur an est, ex tantas expetendis sit. Convenire disputando repudiandae nam no, laudem malorum quaeque sit id.',
36 | [
37 | new Image('http://www.titanui.com/wp-content/uploads/2013/05/18/Wemen-T-Shirt-Vector-Mockup.jpg'),
38 | new Image('https://gcontent.robertsonmarketing.com/store/20160512512/assets/themes/theme1_en/images/home/jun17/hero3_youtube.png')
39 | ]),
40 | new Item('google-t-shirts-white', 'Google T-Shirts(White)', new Category('t-shirt', 'T-Shirts'), 30, 68, 'Pre-Order', 'Lorem ipsum dolor sit amet, no agam populo apeirian pri, ea eirmod scaevola voluptatibus per. No est maluisset sadipscing, duo soluta dignissim dissentiet ei, malis possim posidonium ad has. Dico error utamur an est, ex tantas expetendis sit. Convenire disputando repudiandae nam no, laudem malorum quaeque sit id.',
41 | [
42 | new Image('https://ae01.alicdn.com/kf/HTB1Ep4kIFXXXXXIaXXXq6xXFXXXn/2017-Newest-Mans-T-Shirt-Simple-Summer-font-b-Logo-b-font-font-b-Google-b.jpg'),
43 | new Image('https://76.my/Malaysia/google-logo-t-shirt-onlinepasar-1506-05-OnlinePasar@21.jpg')
44 | ])
45 | ];
46 |
47 | constructor( private http: Http ) { }
48 |
49 | /**
50 | * Get items from the firebase API
51 | */
52 | getItems() {
53 | return this.http.get(this.firbaseApi + 'items.json')
54 | .map((response: Response) => response.json() as Item[]);
55 | }
56 |
57 | /**
58 | * Get an item from the items array by id
59 | * @param id
60 | */
61 | getItem(id: number) {
62 | return this.items[id];
63 | }
64 |
65 | /**
66 | * Used to send/store items to the backend
67 | */
68 | storeItem() {
69 | const body = JSON.stringify(this.items);
70 | return this.http.put(this.firbaseApi + 'items.json', body, {headers: this.header});
71 | }
72 |
73 | // Handle all errors if any
74 | private handleError (error: Response | any) {
75 | // use a remote logging infrastructure
76 | let errMsg: string;
77 | if (error instanceof Response) {
78 | const body = error.json() || '';
79 | const err = body.error || JSON.stringify(body);
80 | errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
81 | } else {
82 | errMsg = error.message ? error.message : error.toString();
83 | }
84 | console.error(errMsg);
85 | return Observable.throw(errMsg);
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/app/items/item.ts:
--------------------------------------------------------------------------------
1 | export class Item {
2 | constructor(
3 | public slug: string,
4 | public name: string,
5 | public category: Category,
6 | public price: number,
7 | public old_price: number,
8 | public availability: string,
9 | public description: string,
10 | public photos: Image[]
11 | ) {}
12 | }
13 |
14 | export class Image {
15 | constructor(public path: string) {}
16 | }
17 |
18 | export class Category {
19 | constructor(public slug: string, public title: string) {}
20 | }
21 |
--------------------------------------------------------------------------------
/src/app/items/items.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { MaterialModule } from '@angular/material';
4 | import { ReactiveFormsModule } from '@angular/forms';
5 |
6 | import {
7 | ItemDetailsComponent,
8 | ItemComponent,
9 | ItemListComponent,
10 | ItemByCategoryComponent
11 | } from './index';
12 | import { ItemRoutingModule } from 'app/items/item-routing.module';
13 | import { CarouselModule } from 'app/shared/carousel.module';
14 |
15 | @NgModule({
16 | imports: [
17 | CommonModule,
18 | ItemRoutingModule,
19 | MaterialModule,
20 | ReactiveFormsModule,
21 | CarouselModule
22 | ],
23 | declarations: [
24 | ItemDetailsComponent,
25 | ItemComponent,
26 | ItemListComponent,
27 | ItemByCategoryComponent
28 | ]
29 | })
30 | export class ItemsModule { }
31 |
--------------------------------------------------------------------------------
/src/app/layouts/default-layout.component.css:
--------------------------------------------------------------------------------
1 |
2 | @media only screen and (min-width: 768px) {
3 | .menu {
4 | display: none;
5 | }
6 | }
7 |
8 | @media only screen and (max-width: 768px) {
9 | .back-arrow {
10 | display: none;
11 | }
12 | }
--------------------------------------------------------------------------------
/src/app/layouts/default-layout.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
19 |
20 |
21 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/src/app/layouts/default-layout.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { Location } from '@angular/common';
3 |
4 | @Component({
5 | selector: 'apfem-default-layout',
6 | templateUrl: './default-layout.component.html',
7 | styleUrls: ['./default-layout.component.css']
8 | })
9 | export class DefaultLayoutComponent implements OnInit {
10 |
11 | constructor(
12 | private location: Location
13 | ) { }
14 |
15 | goBack(): void {
16 | this.location.back();
17 | }
18 |
19 | ngOnInit() {
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/src/app/layouts/index.ts:
--------------------------------------------------------------------------------
1 | export { DefaultLayoutComponent } from './default-layout.component';
2 | export { SimpleLayoutComponent } from './simple-layout.component';
--------------------------------------------------------------------------------
/src/app/layouts/simple-layout.component.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daviskoko/angular-firebase-ecommerce/8c72f065d7f2fe166fbbaf2638872f43ad2a246a/src/app/layouts/simple-layout.component.css
--------------------------------------------------------------------------------
/src/app/layouts/simple-layout.component.html:
--------------------------------------------------------------------------------
1 |
2 | simple-layout works!
3 |
4 |
--------------------------------------------------------------------------------
/src/app/layouts/simple-layout.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'apfem-simple-layout',
5 | templateUrl: './simple-layout.component.html',
6 | styleUrls: ['./simple-layout.component.css']
7 | })
8 | export class SimpleLayoutComponent implements OnInit {
9 |
10 | constructor() { }
11 |
12 | ngOnInit() {
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/src/app/shared/carousel.component.ts:
--------------------------------------------------------------------------------
1 | import {Component, OnDestroy, Input} from '@angular/core';
2 | import { SlideComponent } from './slide.component';
3 |
4 | export enum Direction {UNKNOWN, NEXT, PREV}
5 |
6 | @Component({
7 | selector: 'apfem-carousel',
8 | template: `
9 |
21 | `
22 | })
23 | export class CarouselComponent implements OnDestroy {
24 | @Input() public noWrap: boolean;
25 | @Input() public noPause: boolean;
26 | @Input() public noTransition: boolean;
27 |
28 | @Input() public get interval(): number {
29 | return this._interval;
30 | }
31 |
32 | slides: Array = [];
33 | currentInterval: any;
34 | isPlaying: boolean;
35 | destroyed = false;
36 | currentSlide: SlideComponent;
37 | _interval: number;
38 |
39 | public set interval(value: number) {
40 | this._interval = value;
41 | this.restartTimer();
42 | }
43 |
44 | ngOnDestroy() {
45 | this.destroyed = true;
46 | }
47 |
48 | select(nextSlide: SlideComponent, direction: Direction = Direction.UNKNOWN) {
49 | const nextIndex = nextSlide.index;
50 | if (direction === Direction.UNKNOWN) {
51 | direction = nextIndex > this.getCurrentIndex() ? Direction.NEXT : Direction.PREV;
52 | }
53 |
54 | // Prevent this user-triggered transition from occurring if there is already one in progress
55 | if (nextSlide && nextSlide !== this.currentSlide) {
56 | this.goNext(nextSlide, direction);
57 | }
58 | }
59 |
60 | private goNext(slide: SlideComponent, direction: Direction) {
61 | if (this.destroyed) {
62 | return;
63 | }
64 |
65 | slide.direction = direction;
66 | slide.active = true;
67 |
68 | if (this.currentSlide) {
69 | this.currentSlide.direction = direction;
70 | this.currentSlide.active = false;
71 | }
72 |
73 | this.currentSlide = slide;
74 |
75 | // every time you change slides, reset the timer
76 | this.restartTimer();
77 | }
78 |
79 | private getSlideByIndex(index: number) {
80 | const len = this.slides.length;
81 | for (let i = 0; i < len; ++i) {
82 | if (this.slides[i].index === index) {
83 | return this.slides[i];
84 | }
85 | }
86 | }
87 |
88 | getCurrentIndex() {
89 | return !this.currentSlide ? 0 : this.currentSlide.index;
90 | }
91 |
92 | next() {
93 | const newIndex = (this.getCurrentIndex() + 1) % this.slides.length;
94 |
95 | if (newIndex === 0 && this.noWrap) {
96 | this.pause();
97 | return;
98 | }
99 |
100 | return this.select(this.getSlideByIndex(newIndex), Direction.NEXT);
101 | }
102 |
103 | prev() {
104 | const newIndex = this.getCurrentIndex() - 1 < 0 ? this.slides.length - 1 : this.getCurrentIndex() - 1;
105 |
106 | if (this.noWrap && newIndex === this.slides.length - 1) {
107 | this.pause();
108 | return;
109 | }
110 |
111 | return this.select(this.getSlideByIndex(newIndex), Direction.PREV);
112 | }
113 |
114 | restartTimer() {
115 | this.resetTimer();
116 | const interval = +this.interval;
117 | if (!isNaN(interval) && interval > 0) {
118 | this.currentInterval = setInterval(() => {
119 | const nInterval = +this.interval;
120 | if (this.isPlaying && !isNaN(this.interval) && nInterval > 0 && this.slides.length) {
121 | this.next();
122 | } else {
123 | this.pause();
124 | }
125 | }, interval);
126 | }
127 | }
128 |
129 | resetTimer() {
130 | if (this.currentInterval) {
131 | clearInterval(this.currentInterval);
132 | this.currentInterval = null;
133 | }
134 | }
135 |
136 | public play() {
137 | if (!this.isPlaying) {
138 | this.isPlaying = true;
139 | this.restartTimer();
140 | }
141 | }
142 |
143 | public pause() {
144 | if (!this.noPause) {
145 | this.isPlaying = false;
146 | this.resetTimer();
147 | }
148 | }
149 |
150 | public addSlide(slide: SlideComponent) {
151 | slide.index = this.slides.length;
152 | this.slides.push(slide);
153 | if (this.slides.length === 1 || slide.active) {
154 | this.select(this.slides[this.slides.length - 1]);
155 | if (this.slides.length === 1) {
156 | this.play();
157 | }
158 | } else {
159 | slide.active = false;
160 | }
161 | }
162 |
163 | public removeSlide(slide: SlideComponent) {
164 | this.slides.splice(slide.index, 1);
165 |
166 | if (this.slides.length === 0) {
167 | this.currentSlide = null;
168 | return;
169 | }
170 |
171 | for (let i = 0; i < this.slides.length; i++) {
172 | this.slides[i].index = i;
173 | }
174 | }
175 | }
176 |
177 |
--------------------------------------------------------------------------------
/src/app/shared/carousel.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { MaterialModule } from '@angular/material';
4 |
5 | import { CarouselComponent, SlideComponent } from './index';
6 |
7 | @NgModule({
8 | imports: [
9 | CommonModule,
10 | MaterialModule
11 | ],
12 | exports: [
13 | CarouselComponent,
14 | SlideComponent
15 | ],
16 | declarations: [
17 | CarouselComponent,
18 | SlideComponent
19 | ]
20 | })
21 | export class CarouselModule { }
22 |
--------------------------------------------------------------------------------
/src/app/shared/cart-counter.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 |
3 | import { CartService, Cart } from "../cart";
4 |
5 | @Component({
6 | selector: 'apfem-cart-counter',
7 | template: `
8 |
9 | shopping_cart
10 | {{cart.length}}
11 |
12 | `,
13 | styles: [
14 | '.badge {background-color: #fff; border-radius: 50%; padding: 5px 8px; color: #333;}'
15 | ]
16 | })
17 | export class CartCounterComponent implements OnInit {
18 |
19 | cart: Cart[] = [];
20 |
21 | constructor(
22 | private cartService: CartService
23 | ) { }
24 |
25 | ngOnInit() {
26 | this.cart = this.cartService.getCart();
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/src/app/shared/footer.component.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daviskoko/angular-firebase-ecommerce/8c72f065d7f2fe166fbbaf2638872f43ad2a246a/src/app/shared/footer.component.css
--------------------------------------------------------------------------------
/src/app/shared/footer.component.html:
--------------------------------------------------------------------------------
1 |
11 |
12 |
--------------------------------------------------------------------------------
/src/app/shared/footer.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'apfem-footer',
5 | templateUrl: './footer.component.html',
6 | styleUrls: ['./footer.component.css']
7 | })
8 | export class FooterComponent implements OnInit {
9 |
10 | year: number = Date.now();
11 |
12 | constructor() { }
13 |
14 | ngOnInit() {
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/src/app/shared/index.ts:
--------------------------------------------------------------------------------
1 | export { CarouselComponent } from './carousel.component';
2 | export { SlideComponent } from './slide.component';
3 | export { SideNavComponent } from './side-nav.component';
4 | export { MainNavComponent } from './main-nav.component';
5 | export { FooterComponent } from './footer.component';
6 | export { CartCounterComponent } from './cart-counter.component';
--------------------------------------------------------------------------------
/src/app/shared/main-nav.component.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daviskoko/angular-firebase-ecommerce/8c72f065d7f2fe166fbbaf2638872f43ad2a246a/src/app/shared/main-nav.component.css
--------------------------------------------------------------------------------
/src/app/shared/main-nav.component.html:
--------------------------------------------------------------------------------
1 |
2 | main-nav works!
3 |
4 |
--------------------------------------------------------------------------------
/src/app/shared/main-nav.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'apfem-main-nav',
5 | templateUrl: './main-nav.component.html',
6 | styleUrls: ['./main-nav.component.css']
7 | })
8 | export class MainNavComponent implements OnInit {
9 |
10 | constructor() { }
11 |
12 | ngOnInit() {
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/src/app/shared/side-nav.component.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daviskoko/angular-firebase-ecommerce/8c72f065d7f2fe166fbbaf2638872f43ad2a246a/src/app/shared/side-nav.component.css
--------------------------------------------------------------------------------
/src/app/shared/side-nav.component.html:
--------------------------------------------------------------------------------
1 |
2 | side-nav works!
3 |
4 |
--------------------------------------------------------------------------------
/src/app/shared/side-nav.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'apfem-side-nav',
5 | templateUrl: './side-nav.component.html',
6 | styleUrls: ['./side-nav.component.css']
7 | })
8 | export class SideNavComponent implements OnInit {
9 |
10 | constructor() { }
11 |
12 | ngOnInit() {
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/src/app/shared/slide.component.ts:
--------------------------------------------------------------------------------
1 | import {Component, OnInit, OnDestroy, Input, HostBinding } from '@angular/core';
2 |
3 | import { CarouselComponent, Direction} from './carousel.component';
4 |
5 | @Component({
6 | selector: 'apfem-slide',
7 | template: `
8 |
9 |
10 |
11 | `
12 | })
13 | export class SlideComponent implements OnInit, OnDestroy {
14 | @Input() public index:number;
15 | @Input() public direction:Direction;
16 |
17 | @HostBinding('class.active')
18 | @Input() public active:boolean;
19 |
20 | @HostBinding('class.item')
21 | @HostBinding('class.carousel-item')
22 | private addClass:boolean = true;
23 |
24 | constructor(private carousel:CarouselComponent) {
25 | }
26 |
27 | public ngOnInit() {
28 | this.carousel.addSlide(this);
29 | }
30 |
31 | public ngOnDestroy() {
32 | this.carousel.removeSlide(this);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/assets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daviskoko/angular-firebase-ecommerce/8c72f065d7f2fe166fbbaf2638872f43ad2a246a/src/assets/.gitkeep
--------------------------------------------------------------------------------
/src/assets/bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daviskoko/angular-firebase-ecommerce/8c72f065d7f2fe166fbbaf2638872f43ad2a246a/src/assets/bg.jpg
--------------------------------------------------------------------------------
/src/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true
3 | };
4 |
--------------------------------------------------------------------------------
/src/environments/environment.ts:
--------------------------------------------------------------------------------
1 | // The file contents for the current environment will overwrite these during build.
2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do
3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead.
4 | // The list of which env maps to which file can be found in `.angular-cli.json`.
5 |
6 | export const environment = {
7 | production: false
8 | };
9 |
--------------------------------------------------------------------------------
/src/fav.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daviskoko/angular-firebase-ecommerce/8c72f065d7f2fe166fbbaf2638872f43ad2a246a/src/fav.png
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | APFEM SHOP
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/main.ts:
--------------------------------------------------------------------------------
1 | import { enableProdMode } from '@angular/core';
2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
3 |
4 | import { AppModule } from './app/app.module';
5 | import { environment } from './environments/environment';
6 |
7 | if (environment.production) {
8 | enableProdMode();
9 | }
10 |
11 | platformBrowserDynamic().bootstrapModule(AppModule);
12 |
--------------------------------------------------------------------------------
/src/polyfills.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This file includes polyfills needed by Angular and is loaded before the app.
3 | * You can add your own extra polyfills to this file.
4 | *
5 | * This file is divided into 2 sections:
6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main
8 | * file.
9 | *
10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
13 | *
14 | * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html
15 | */
16 |
17 | /***************************************************************************************************
18 | * BROWSER POLYFILLS
19 | */
20 |
21 | /** IE9, IE10 and IE11 requires all of the following polyfills. **/
22 | // import 'core-js/es6/symbol';
23 | // import 'core-js/es6/object';
24 | // import 'core-js/es6/function';
25 | // import 'core-js/es6/parse-int';
26 | // import 'core-js/es6/parse-float';
27 | // import 'core-js/es6/number';
28 | // import 'core-js/es6/math';
29 | // import 'core-js/es6/string';
30 | // import 'core-js/es6/date';
31 | // import 'core-js/es6/array';
32 | // import 'core-js/es6/regexp';
33 | // import 'core-js/es6/map';
34 | // import 'core-js/es6/weak-map';
35 | // import 'core-js/es6/set';
36 |
37 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */
38 | // import 'classlist.js'; // Run `npm install --save classlist.js`.
39 |
40 | /** IE10 and IE11 requires the following to support `@angular/animation`. */
41 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`.
42 |
43 |
44 | /** Evergreen browsers require these. **/
45 | import 'core-js/es6/reflect';
46 | import 'core-js/es7/reflect';
47 |
48 |
49 | /** ALL Firefox browsers require the following to support `@angular/animation`. **/
50 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`.
51 |
52 |
53 |
54 | /***************************************************************************************************
55 | * Zone JS is required by Angular itself.
56 | */
57 | import 'zone.js/dist/zone'; // Included with Angular CLI.
58 |
59 |
60 |
61 | /***************************************************************************************************
62 | * APPLICATION IMPORTS
63 | */
64 |
65 | /**
66 | * Date, currency, decimal and percent pipes.
67 | * Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10
68 | */
69 | // import 'intl'; // Run `npm install --save intl`.
70 | /**
71 | * Need to import at least one locale-data with intl.
72 | */
73 | // import 'intl/locale-data/jsonp/en';
74 |
--------------------------------------------------------------------------------
/src/styles.css:
--------------------------------------------------------------------------------
1 | /* You can add global styles to this file, and also import other style files */
2 | @import '~https://cdnjs.cloudflare.com/ajax/libs/flexboxgrid/6.3.1/flexboxgrid.min.css';
3 | @import '~https://fonts.googleapis.com/icon?family=Material+Icons';
4 | @import '~https://fonts.googleapis.com/css?family=Quicksand';
5 |
6 | html, body, material-app, md-sidenav-container, .my-content {
7 | margin: 0px auto;
8 | width: 100%;
9 | height: 100%;
10 | font-family: 'Quicksand', sans-serif;
11 | background-color: #f9f9f9;
12 | color: #333;
13 | }
14 | h4 {
15 | color: gray;
16 | margin: 5px 0px;
17 | }
18 | a {
19 | text-decoration: none;
20 | }
21 |
22 | .content {
23 | display: block;
24 | position: relative;
25 | }
26 |
27 | .content::after {
28 | content: "";
29 | background: url('./assets/bg.jpg');
30 | opacity: 0.04;
31 | top: 0;
32 | left: 0;
33 | bottom: 0;
34 | right: 0;
35 | position: absolute;
36 | z-index: -1;
37 | }
38 | .brand {
39 | color: #FFF;
40 | text-decoration: none;
41 | font-weight: bold;
42 | letter-spacing: 5px;
43 | font-size: 2vmax;
44 | }
45 | .container {
46 | padding: 0px 5px;
47 | }
48 |
49 | md-toolbar-row {
50 | justify-content: space-between;
51 | }
52 |
53 | md-sidenav {
54 | width: 200px;
55 | }
56 |
57 | .old-price {
58 | color: darkred;
59 | text-decoration: line-through;
60 | }
61 |
62 | .loader {
63 | position: absolute;
64 | top: 50%;
65 | left: 50%;
66 | margin-right: -50%;
67 | border: 10px solid #f3f3f3;
68 | border-top: 10px solid #3498db;
69 | border-radius: 50%;
70 | width: 50px;
71 | height: 50px;
72 | animation: spin 2s linear infinite;
73 | }
74 |
75 | @keyframes spin {
76 | 0% { transform: rotate(0deg); }
77 | 100% { transform: rotate(360deg); }
78 | }
79 |
80 | /*Thanks to Twitter Bootstrap*/
81 | .carousel {
82 | position: relative;
83 | }
84 | .carousel-inner {
85 | position: relative;
86 | overflow: hidden;
87 | width: 100%;
88 | }
89 | .carousel-inner > .item {
90 | display: none;
91 | position: relative;
92 | -webkit-transition: 0.6s ease-in-out left;
93 | transition: 0.6s ease-in-out left;
94 | }
95 | .carousel-inner > .item > img,
96 | .carousel-inner > .item > a > img {
97 | line-height: 1;
98 | }
99 | .carousel-inner > .active,
100 | .carousel-inner > .next,
101 | .carousel-inner > .prev {
102 | display: block;
103 | }
104 | .carousel-inner > .active {
105 | left: 0;
106 | }
107 | .carousel-inner > .next,
108 | .carousel-inner > .prev {
109 | position: absolute;
110 | top: 0;
111 | width: 100%;
112 | }
113 | .carousel-inner > .next {
114 | left: 100%;
115 | }
116 | .carousel-inner > .prev {
117 | left: -100%;
118 | }
119 | .carousel-inner > .next.left,
120 | .carousel-inner > .prev.right {
121 | left: 0;
122 | }
123 | .carousel-inner > .active.left {
124 | left: -100%;
125 | }
126 | .carousel-inner > .active.right {
127 | left: 100%;
128 | }
129 | .carousel-control {
130 | position: absolute;
131 | top: 0;
132 | left: 0;
133 | bottom: 0;
134 | width: 15%;
135 | opacity: .5;
136 | filter: alpha(opacity=50);
137 | font-size: 20px;
138 | color: #fff;
139 | text-align: center;
140 | text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8);
141 | }
142 | .carousel-control.right {
143 | left: auto;
144 | right: 0;
145 | }
146 | .carousel-control:hover,
147 | .carousel-control:focus {
148 | outline: none;
149 | color: #fff;
150 | text-decoration: none;
151 | opacity: .9;
152 | filter: alpha(opacity=90);
153 | }
154 | .carousel-control .icon-prev,
155 | .carousel-control .icon-next,
156 | .carousel-control .glyphicon-chevron-left,
157 | .carousel-control .glyphicon-chevron-right {
158 | position: absolute;
159 | top: 50%;
160 | z-index: 5;
161 | display: inline-block;
162 | }
163 | .carousel-control .icon-prev,
164 | .carousel-control .glyphicon-chevron-left {
165 | left: 50%;
166 | }
167 | .carousel-control .icon-next,
168 | .carousel-control .glyphicon-chevron-right {
169 | right: 50%;
170 | }
171 | .carousel-control .icon-prev,
172 | .carousel-control .icon-next {
173 | width: 20px;
174 | height: 20px;
175 | margin-top: -10px;
176 | margin-left: -10px;
177 | font-family: serif;
178 | }
179 | .carousel-control .icon-prev:before {
180 | content: '\2039';
181 | }
182 | .carousel-control .icon-next:before {
183 | content: '\203a';
184 | }
185 | .carousel-indicators {
186 | position: absolute;
187 | bottom: 10px;
188 | left: 50%;
189 | z-index: 15;
190 | width: 60%;
191 | margin-left: -30%;
192 | padding-left: 0;
193 | list-style: none;
194 | text-align: center;
195 | }
196 | .carousel-indicators li {
197 | display: inline-block;
198 | width: 10px;
199 | height: 10px;
200 | margin: 1px;
201 | text-indent: -999px;
202 | border: 1px solid #fff;
203 | border-radius: 10px;
204 | cursor: pointer;
205 | background-color: #000 \9;
206 | background-color: rgba(0, 0, 0, 0);
207 | }
208 | .carousel-indicators .active {
209 | margin: 0;
210 | width: 12px;
211 | height: 12px;
212 | background-color: #ffffff;
213 | }
214 | .carousel-caption {
215 | position: absolute;
216 | left: 15%;
217 | right: 15%;
218 | bottom: 20px;
219 | z-index: 10;
220 | padding-top: 20px;
221 | padding-bottom: 20px;
222 | color: #fff;
223 | text-align: center;
224 | text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
225 | }
226 | .carousel-caption .btn {
227 | text-shadow: none;
228 | }
229 | .carousel-icon {
230 | font-size: 5vmin;
231 | cursor: pointer;
232 | width: auto !important;
233 | height: auto !important;
234 | }
235 | /*End of carousel*/
--------------------------------------------------------------------------------
/src/test.ts:
--------------------------------------------------------------------------------
1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files
2 |
3 | import 'zone.js/dist/long-stack-trace-zone';
4 | import 'zone.js/dist/proxy.js';
5 | import 'zone.js/dist/sync-test';
6 | import 'zone.js/dist/jasmine-patch';
7 | import 'zone.js/dist/async-test';
8 | import 'zone.js/dist/fake-async-test';
9 | import { getTestBed } from '@angular/core/testing';
10 | import {
11 | BrowserDynamicTestingModule,
12 | platformBrowserDynamicTesting
13 | } from '@angular/platform-browser-dynamic/testing';
14 |
15 | // Unfortunately there's no typing for the `__karma__` variable. Just declare it as any.
16 | declare const __karma__: any;
17 | declare const require: any;
18 |
19 | // Prevent Karma from running prematurely.
20 | __karma__.loaded = function () {};
21 |
22 | // First, initialize the Angular testing environment.
23 | getTestBed().initTestEnvironment(
24 | BrowserDynamicTestingModule,
25 | platformBrowserDynamicTesting()
26 | );
27 | // Then we find all the tests.
28 | const context = require.context('./', true, /\.spec\.ts$/);
29 | // And load the modules.
30 | context.keys().map(context);
31 | // Finally, start Karma to run the tests.
32 | __karma__.start();
33 |
--------------------------------------------------------------------------------
/src/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../out-tsc/app",
5 | "module": "es2015",
6 | "baseUrl": "",
7 | "types": []
8 | },
9 | "exclude": [
10 | "test.ts",
11 | "**/*.spec.ts"
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/src/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../out-tsc/spec",
5 | "module": "commonjs",
6 | "target": "es5",
7 | "baseUrl": "",
8 | "types": [
9 | "jasmine",
10 | "node"
11 | ]
12 | },
13 | "files": [
14 | "test.ts"
15 | ],
16 | "include": [
17 | "**/*.spec.ts",
18 | "**/*.d.ts"
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/src/typings.d.ts:
--------------------------------------------------------------------------------
1 | /* SystemJS module definition */
2 | declare var module: NodeModule;
3 | interface NodeModule {
4 | id: string;
5 | }
6 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "outDir": "./dist/out-tsc",
5 | "baseUrl": "src",
6 | "sourceMap": true,
7 | "declaration": false,
8 | "moduleResolution": "node",
9 | "emitDecoratorMetadata": true,
10 | "experimentalDecorators": true,
11 | "target": "es5",
12 | "typeRoots": [
13 | "node_modules/@types"
14 | ],
15 | "lib": [
16 | "es2016",
17 | "dom"
18 | ]
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rulesDirectory": [
3 | "node_modules/codelyzer"
4 | ],
5 | "rules": {
6 | "arrow-return-shorthand": true,
7 | "callable-types": true,
8 | "class-name": true,
9 | "comment-format": [
10 | true,
11 | "check-space"
12 | ],
13 | "curly": true,
14 | "eofline": true,
15 | "forin": true,
16 | "import-blacklist": [
17 | true,
18 | "rxjs"
19 | ],
20 | "import-spacing": true,
21 | "indent": [
22 | true,
23 | "spaces"
24 | ],
25 | "interface-over-type-literal": true,
26 | "label-position": true,
27 | "max-line-length": [
28 | true,
29 | 140
30 | ],
31 | "member-access": false,
32 | "member-ordering": [
33 | true,
34 | "static-before-instance",
35 | "variables-before-functions"
36 | ],
37 | "no-arg": true,
38 | "no-bitwise": true,
39 | "no-console": [
40 | true,
41 | "debug",
42 | "info",
43 | "time",
44 | "timeEnd",
45 | "trace"
46 | ],
47 | "no-construct": true,
48 | "no-debugger": true,
49 | "no-duplicate-super": true,
50 | "no-empty": false,
51 | "no-empty-interface": true,
52 | "no-eval": true,
53 | "no-inferrable-types": [
54 | true,
55 | "ignore-params"
56 | ],
57 | "no-misused-new": true,
58 | "no-non-null-assertion": true,
59 | "no-shadowed-variable": true,
60 | "no-string-literal": false,
61 | "no-string-throw": true,
62 | "no-switch-case-fall-through": true,
63 | "no-trailing-whitespace": true,
64 | "no-unnecessary-initializer": true,
65 | "no-unused-expression": true,
66 | "no-use-before-declare": true,
67 | "no-var-keyword": true,
68 | "object-literal-sort-keys": false,
69 | "one-line": [
70 | true,
71 | "check-open-brace",
72 | "check-catch",
73 | "check-else",
74 | "check-whitespace"
75 | ],
76 | "prefer-const": true,
77 | "quotemark": [
78 | true,
79 | "single"
80 | ],
81 | "radix": true,
82 | "semicolon": [
83 | "always"
84 | ],
85 | "triple-equals": [
86 | true,
87 | "allow-null-check"
88 | ],
89 | "typedef-whitespace": [
90 | true,
91 | {
92 | "call-signature": "nospace",
93 | "index-signature": "nospace",
94 | "parameter": "nospace",
95 | "property-declaration": "nospace",
96 | "variable-declaration": "nospace"
97 | }
98 | ],
99 | "typeof-compare": true,
100 | "unified-signatures": true,
101 | "variable-name": false,
102 | "whitespace": [
103 | true,
104 | "check-branch",
105 | "check-decl",
106 | "check-operator",
107 | "check-separator",
108 | "check-type"
109 | ],
110 | "directive-selector": [
111 | true,
112 | "attribute",
113 | "app",
114 | "camelCase"
115 | ],
116 | "component-selector": [
117 | true,
118 | "element",
119 | "app",
120 | "kebab-case"
121 | ],
122 | "use-input-property-decorator": true,
123 | "use-output-property-decorator": true,
124 | "use-host-property-decorator": true,
125 | "no-input-rename": true,
126 | "no-output-rename": true,
127 | "use-life-cycle-interface": true,
128 | "use-pipe-transform-interface": true,
129 | "component-class-suffix": true,
130 | "directive-class-suffix": true,
131 | "no-access-missing-member": true,
132 | "templates-use-public": true,
133 | "invoke-injectable": true
134 | }
135 | }
136 |
--------------------------------------------------------------------------------