| @@ -193,6 +193,77 @@ | |||
| "tslib": "1.8.0" | |||
| } | |||
| }, | |||
| "@firebase/app": { | |||
| "version": "0.1.2", | |||
| "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.1.2.tgz", | |||
| "integrity": "sha512-H2moN0Dl5LJn1AiRsCvwJsfE7PLKYYYJc+WKqAta+qIB/ZzBAay8NTVBYHiqsteLHc7gXofoi8zEUrGjbmz4OQ==", | |||
| "requires": { | |||
| "@firebase/util": "0.1.2" | |||
| } | |||
| }, | |||
| "@firebase/auth": { | |||
| "version": "0.2.2", | |||
| "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-0.2.2.tgz", | |||
| "integrity": "sha512-/qUnCjil7Eb0KQVErkziuyIbG1FrszD6+ttGY7+DTTbN+/QGjyqwTizwGLQDF8Itvf29O7YWKEdsoJyiwn/F4Q==" | |||
| }, | |||
| "@firebase/database": { | |||
| "version": "0.1.3", | |||
| "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.1.3.tgz", | |||
| "integrity": "sha512-Uk9IRPYDmpDRBvnIZhs16iQX/7GxetslWD+7N6GKgEDmO9csPC+9hHmdXkcVc6cG7xHCePdRJGvhrVt3ax7Fcw==", | |||
| "requires": { | |||
| "@firebase/util": "0.1.2", | |||
| "faye-websocket": "0.11.1" | |||
| }, | |||
| "dependencies": { | |||
| "faye-websocket": { | |||
| "version": "0.11.1", | |||
| "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz", | |||
| "integrity": "sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=", | |||
| "requires": { | |||
| "websocket-driver": "0.7.0" | |||
| } | |||
| } | |||
| } | |||
| }, | |||
| "@firebase/firestore": { | |||
| "version": "0.1.4", | |||
| "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-0.1.4.tgz", | |||
| "integrity": "sha512-ltt3zvvZ6LE37oIfVm0zeNA0DPo75YKWkfIyEbFlXDWkeNIt3lunhB4L777weUzZOmcZhX8T6pHx6xZM+ysDkA==", | |||
| "requires": { | |||
| "@firebase/webchannel-wrapper": "0.2.4" | |||
| } | |||
| }, | |||
| "@firebase/messaging": { | |||
| "version": "0.1.3", | |||
| "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.1.3.tgz", | |||
| "integrity": "sha512-mQxG4y+wT7hCSsNzPGdFKjZ7/NLIdSJRYX59bLL3F0HMIuOlNtYXxKjN23vBGljwFufx3dQBtlX8beDBKbOv4Q==", | |||
| "requires": { | |||
| "@firebase/util": "0.1.2" | |||
| } | |||
| }, | |||
| "@firebase/polyfill": { | |||
| "version": "0.1.2", | |||
| "resolved": "https://registry.npmjs.org/@firebase/polyfill/-/polyfill-0.1.2.tgz", | |||
| "integrity": "sha512-5oneu9nOYDZkZWyfvBXFa+ORWj9HeOYhwWy4HSJzCLKLnOvQSSZRcNBD2cVrysGR8tZCEfyKqq3fnwtODCvIQg==", | |||
| "requires": { | |||
| "promise-polyfill": "6.1.0" | |||
| } | |||
| }, | |||
| "@firebase/storage": { | |||
| "version": "0.1.2", | |||
| "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.1.2.tgz", | |||
| "integrity": "sha512-Il1+R2BbFfhwq4H6OAF+hpxr5mAxoD3CK/i/78CiDATtKR5OU9kuQf7T3V3khMeFspK0H6r02Oe9gTbS2XhPkQ==" | |||
| }, | |||
| "@firebase/util": { | |||
| "version": "0.1.2", | |||
| "resolved": "https://registry.npmjs.org/@firebase/util/-/util-0.1.2.tgz", | |||
| "integrity": "sha512-XzvnxTsPIukAJmBVpBOGTLVgz27Iyoudmum6Bqy8Czu2qhWjikhkE1UlND7Gh5BwTpBVr03axjovRXgh5xgIxw==" | |||
| }, | |||
| "@firebase/webchannel-wrapper": { | |||
| "version": "0.2.4", | |||
| "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.2.4.tgz", | |||
| "integrity": "sha512-jEpglcwMlwdXc/JgvJaJtCSkPMktnFeI0gAZxPrmbJxKVzMZJ2zM582NbW/r6M22pSdNWjcWeg1I2LRg3jQGQA==" | |||
| }, | |||
| "@ngtools/json-schema": { | |||
| "version": "1.1.0", | |||
| "resolved": "https://registry.npmjs.org/@ngtools/json-schema/-/json-schema-1.1.0.tgz", | |||
| @@ -2152,6 +2223,11 @@ | |||
| } | |||
| } | |||
| }, | |||
| "dom-storage": { | |||
| "version": "2.0.2", | |||
| "resolved": "https://registry.npmjs.org/dom-storage/-/dom-storage-2.0.2.tgz", | |||
| "integrity": "sha1-7RfL9oq9EOCu+BgnE+KXxeS1ALA=" | |||
| }, | |||
| "domain-browser": { | |||
| "version": "1.1.7", | |||
| "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz", | |||
| @@ -2910,6 +2986,22 @@ | |||
| "pinkie-promise": "2.0.1" | |||
| } | |||
| }, | |||
| "firebase": { | |||
| "version": "4.6.2", | |||
| "resolved": "https://registry.npmjs.org/firebase/-/firebase-4.6.2.tgz", | |||
| "integrity": "sha512-qI4qWZNO4/tS05goNaLYaxFd2/GgWVONPcqq+H1YyLi0ybWfF7oEVhw1dz8SY+7Xc5wc3S4jGSMi3apgINz1Zg==", | |||
| "requires": { | |||
| "@firebase/app": "0.1.2", | |||
| "@firebase/auth": "0.2.2", | |||
| "@firebase/database": "0.1.3", | |||
| "@firebase/firestore": "0.1.4", | |||
| "@firebase/messaging": "0.1.3", | |||
| "@firebase/polyfill": "0.1.2", | |||
| "@firebase/storage": "0.1.2", | |||
| "dom-storage": "2.0.2", | |||
| "xmlhttprequest": "1.8.0" | |||
| } | |||
| }, | |||
| "flatten": { | |||
| "version": "1.0.2", | |||
| "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz", | |||
| @@ -3565,8 +3657,7 @@ | |||
| "http-parser-js": { | |||
| "version": "0.4.9", | |||
| "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.9.tgz", | |||
| "integrity": "sha1-6hoE+2St/wJC6ZdPKX3Uw8rSceE=", | |||
| "dev": true | |||
| "integrity": "sha1-6hoE+2St/wJC6ZdPKX3Uw8rSceE=" | |||
| }, | |||
| "http-proxy": { | |||
| "version": "1.16.2", | |||
| @@ -6612,6 +6703,11 @@ | |||
| "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", | |||
| "dev": true | |||
| }, | |||
| "promise-polyfill": { | |||
| "version": "6.1.0", | |||
| "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-6.1.0.tgz", | |||
| "integrity": "sha1-36lpQ+qcEh/KTem1hoyznTRy4Fc=" | |||
| }, | |||
| "protractor": { | |||
| "version": "5.1.2", | |||
| "resolved": "https://registry.npmjs.org/protractor/-/protractor-5.1.2.tgz", | |||
| @@ -9221,7 +9317,6 @@ | |||
| "version": "0.7.0", | |||
| "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz", | |||
| "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", | |||
| "dev": true, | |||
| "requires": { | |||
| "http-parser-js": "0.4.9", | |||
| "websocket-extensions": "0.1.3" | |||
| @@ -9230,8 +9325,7 @@ | |||
| "websocket-extensions": { | |||
| "version": "0.1.3", | |||
| "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", | |||
| "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", | |||
| "dev": true | |||
| "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==" | |||
| }, | |||
| "when": { | |||
| "version": "3.6.4", | |||
| @@ -9351,6 +9445,11 @@ | |||
| "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=", | |||
| "dev": true | |||
| }, | |||
| "xmlhttprequest": { | |||
| "version": "1.8.0", | |||
| "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", | |||
| "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=" | |||
| }, | |||
| "xmlhttprequest-ssl": { | |||
| "version": "1.5.3", | |||
| "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz", | |||
| @@ -23,6 +23,7 @@ | |||
| "@angular/router": "^5.0.0", | |||
| "bootstrap": "^3.3.7", | |||
| "core-js": "^2.4.1", | |||
| "firebase": "^4.6.2", | |||
| "rxjs": "^5.5.2", | |||
| "zone.js": "^0.8.14" | |||
| }, | |||
| @@ -6,6 +6,8 @@ import { ShoppingListComponent } from './shopping-list/shopping-list.component'; | |||
| import { RecipeDetailComponent } from './recipes/recipe-detail/recipe-detail.component'; | |||
| import { RecipeStartComponent } from './recipes/recipe-start/recipe-start.component'; | |||
| import { RecipeEditComponent } from './recipes/recipe-edit/recipe-edit.component'; | |||
| import { SignupComponent } from './auth/signup/signup.component'; | |||
| import { SigninComponent } from './auth/signin/signin.component'; | |||
| const appRoutes: Routes = [ | |||
| { path: '', redirectTo: '/recipes', pathMatch: 'full' }, | |||
| @@ -15,7 +17,9 @@ const appRoutes: Routes = [ | |||
| { path: ':id', component: RecipeDetailComponent }, | |||
| { path: ':id/edit', component: RecipeEditComponent} | |||
| ] }, | |||
| { path: 'shopping-list', component: ShoppingListComponent } | |||
| { path: 'shopping-list', component: ShoppingListComponent }, | |||
| { path: 'signup', component: SignupComponent }, | |||
| { path: 'signin', component: SigninComponent } | |||
| ]; | |||
| @NgModule({ | |||
| @@ -1,13 +1,21 @@ | |||
| import { Component } from '@angular/core'; | |||
| import { Component, OnInit } from '@angular/core'; | |||
| import * as firebase from 'firebase'; | |||
| @Component({ | |||
| selector: 'app-root', | |||
| templateUrl: './app.component.html', | |||
| styleUrls: ['./app.component.css'] | |||
| }) | |||
| export class AppComponent { | |||
| export class AppComponent implements OnInit { | |||
| loadedFeature = 'recipe'; | |||
| ngOnInit() { | |||
| firebase.initializeApp({ | |||
| apiKey: "AIzaSyB_-OMDNvUHDfSOzbpW8uHIxlTF8CaZHZo", | |||
| authDomain: "my-recipe-book-cb837.firebaseapp.com" | |||
| }); | |||
| } | |||
| onNavigate(feature: string) { | |||
| this.loadedFeature = feature; | |||
| } | |||
| @@ -20,6 +20,9 @@ import { RecipeStartComponent } from './recipes/recipe-start/recipe-start.compon | |||
| import { RecipeEditComponent } from './recipes/recipe-edit/recipe-edit.component'; | |||
| import { RecipeService } from './recipes/recipe.service'; | |||
| import { DataStorageService } from './shared/data-storage.service'; | |||
| import { SignupComponent } from './auth/signup/signup.component'; | |||
| import { SigninComponent } from './auth/signin/signin.component'; | |||
| import { AuthService } from './auth/auth.service'; | |||
| @NgModule({ | |||
| @@ -34,7 +37,9 @@ import { DataStorageService } from './shared/data-storage.service'; | |||
| ShoppingEditComponent, | |||
| DropdownDirective, | |||
| RecipeStartComponent, | |||
| RecipeEditComponent | |||
| RecipeEditComponent, | |||
| SignupComponent, | |||
| SigninComponent | |||
| ], | |||
| imports: [ | |||
| BrowserModule, | |||
| @@ -44,7 +49,7 @@ import { DataStorageService } from './shared/data-storage.service'; | |||
| HttpModule, | |||
| AppRoutingModule | |||
| ], | |||
| providers: [ShoppingListService, RecipeService, DataStorageService], | |||
| providers: [ShoppingListService, RecipeService, DataStorageService, AuthService], | |||
| bootstrap: [AppComponent] | |||
| }) | |||
| export class AppModule { } | |||
| @@ -0,0 +1,19 @@ | |||
| import * as firebase from 'firebase'; | |||
| export class AuthService { | |||
| signupUser(email: string, password: string) { | |||
| firebase.auth().createUserWithEmailAndPassword(email, password).catch( | |||
| error => console.log(error) | |||
| ); | |||
| } | |||
| signinUser(email: string, password: string) { | |||
| firebase.auth().signInWithEmailAndPassword(email, password) | |||
| .then( | |||
| response => console.log(response) | |||
| ) | |||
| .catch( | |||
| error => console.log(error) | |||
| ); | |||
| } | |||
| } | |||
| @@ -0,0 +1,15 @@ | |||
| <div class="row"> | |||
| <div class="col-xs-12 col-sm-10 col-md-8 col-sm-offset-1 col-md-offset-2"> | |||
| <form (ngSubmit)="onSignin(f)" #f="ngForm"> | |||
| <div class="form-group"> | |||
| <label for="email">Mail</label> | |||
| <input type="email" name="email" id="email" ngModel class="form-control"> | |||
| </div> | |||
| <div class="form-group"> | |||
| <label for="password">Password</label> | |||
| <input type="password" name="password" id="password" ngModel class="form-control"> | |||
| </div> | |||
| <button class="btn btn-primary" type="submit">Sign In</button> | |||
| </form> | |||
| </div> | |||
| </div> | |||
| @@ -0,0 +1,23 @@ | |||
| import { Component, OnInit } from '@angular/core'; | |||
| import { NgForm } from '@angular/forms'; | |||
| import { AuthService } from '../auth.service'; | |||
| @Component({ | |||
| selector: 'app-signin', | |||
| templateUrl: './signin.component.html', | |||
| styleUrls: ['./signin.component.css'] | |||
| }) | |||
| export class SigninComponent implements OnInit { | |||
| constructor(private authService: AuthService) { } | |||
| ngOnInit() { | |||
| } | |||
| onSignin(form: NgForm) { | |||
| const email = form.value.email; | |||
| const password = form.value.password; | |||
| this.authService.signinUser(email, password); | |||
| } | |||
| } | |||
| @@ -0,0 +1,15 @@ | |||
| <div class="row"> | |||
| <div class="col-xs-12 col-sm-10 col-md-8 col-sm-offset-1 col-md-offset-2"> | |||
| <form (ngSubmit)="onSignup(f)" #f="ngForm"> | |||
| <div class="form-group"> | |||
| <label for="email">Mail</label> | |||
| <input type="email" name="email" id="email" ngModel class="form-control"> | |||
| </div> | |||
| <div class="form-group"> | |||
| <label for="password">Password</label> | |||
| <input type="password" name="password" id="password" ngModel class="form-control"> | |||
| </div> | |||
| <button class="btn btn-primary" type="submit">Sign Up</button> | |||
| </form> | |||
| </div> | |||
| </div> | |||
| @@ -0,0 +1,23 @@ | |||
| import { Component, OnInit } from '@angular/core'; | |||
| import { NgForm } from '@angular/forms'; | |||
| import { AuthService } from '../auth.service'; | |||
| @Component({ | |||
| selector: 'app-signup', | |||
| templateUrl: './signup.component.html', | |||
| styleUrls: ['./signup.component.css'] | |||
| }) | |||
| export class SignupComponent implements OnInit { | |||
| constructor(private authService: AuthService) { } | |||
| ngOnInit() { | |||
| } | |||
| onSignup(form: NgForm) { | |||
| const email = form.value.email; | |||
| const password = form.value.password; | |||
| this.authService.signupUser(email, password); | |||
| } | |||
| } | |||
| @@ -10,6 +10,8 @@ | |||
| <li routerLinkActive="active"><a routerLink="/shopping-list">Shopping List</a></li> | |||
| </ul> | |||
| <ul class="nav navbar-nav navbar-right"> | |||
| <li><a routerLink="/signup">Register</a></li> | |||
| <li><a routerLink="/signin">Login</a></li> | |||
| <li class="dropdown" appDropdown> | |||
| <a style="cursor: pointer;" class="dropdown-toggle" role="button">Manage <span class="caret"></span></a> | |||
| <ul class="dropdown-menu"> | |||