| @@ -193,6 +193,77 @@ | |||||
| "tslib": "1.8.0" | "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": { | "@ngtools/json-schema": { | ||||
| "version": "1.1.0", | "version": "1.1.0", | ||||
| "resolved": "https://registry.npmjs.org/@ngtools/json-schema/-/json-schema-1.1.0.tgz", | "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": { | "domain-browser": { | ||||
| "version": "1.1.7", | "version": "1.1.7", | ||||
| "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz", | "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz", | ||||
| @@ -2910,6 +2986,22 @@ | |||||
| "pinkie-promise": "2.0.1" | "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": { | "flatten": { | ||||
| "version": "1.0.2", | "version": "1.0.2", | ||||
| "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz", | "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz", | ||||
| @@ -3565,8 +3657,7 @@ | |||||
| "http-parser-js": { | "http-parser-js": { | ||||
| "version": "0.4.9", | "version": "0.4.9", | ||||
| "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.9.tgz", | "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": { | "http-proxy": { | ||||
| "version": "1.16.2", | "version": "1.16.2", | ||||
| @@ -6612,6 +6703,11 @@ | |||||
| "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", | "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", | ||||
| "dev": true | "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": { | "protractor": { | ||||
| "version": "5.1.2", | "version": "5.1.2", | ||||
| "resolved": "https://registry.npmjs.org/protractor/-/protractor-5.1.2.tgz", | "resolved": "https://registry.npmjs.org/protractor/-/protractor-5.1.2.tgz", | ||||
| @@ -9221,7 +9317,6 @@ | |||||
| "version": "0.7.0", | "version": "0.7.0", | ||||
| "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz", | "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz", | ||||
| "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", | "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", | ||||
| "dev": true, | |||||
| "requires": { | "requires": { | ||||
| "http-parser-js": "0.4.9", | "http-parser-js": "0.4.9", | ||||
| "websocket-extensions": "0.1.3" | "websocket-extensions": "0.1.3" | ||||
| @@ -9230,8 +9325,7 @@ | |||||
| "websocket-extensions": { | "websocket-extensions": { | ||||
| "version": "0.1.3", | "version": "0.1.3", | ||||
| "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", | "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", | ||||
| "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", | |||||
| "dev": true | |||||
| "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==" | |||||
| }, | }, | ||||
| "when": { | "when": { | ||||
| "version": "3.6.4", | "version": "3.6.4", | ||||
| @@ -9351,6 +9445,11 @@ | |||||
| "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=", | "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=", | ||||
| "dev": true | "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": { | "xmlhttprequest-ssl": { | ||||
| "version": "1.5.3", | "version": "1.5.3", | ||||
| "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz", | "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz", | ||||
| @@ -23,6 +23,7 @@ | |||||
| "@angular/router": "^5.0.0", | "@angular/router": "^5.0.0", | ||||
| "bootstrap": "^3.3.7", | "bootstrap": "^3.3.7", | ||||
| "core-js": "^2.4.1", | "core-js": "^2.4.1", | ||||
| "firebase": "^4.6.2", | |||||
| "rxjs": "^5.5.2", | "rxjs": "^5.5.2", | ||||
| "zone.js": "^0.8.14" | "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 { RecipeDetailComponent } from './recipes/recipe-detail/recipe-detail.component'; | ||||
| import { RecipeStartComponent } from './recipes/recipe-start/recipe-start.component'; | import { RecipeStartComponent } from './recipes/recipe-start/recipe-start.component'; | ||||
| import { RecipeEditComponent } from './recipes/recipe-edit/recipe-edit.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 = [ | const appRoutes: Routes = [ | ||||
| { path: '', redirectTo: '/recipes', pathMatch: 'full' }, | { path: '', redirectTo: '/recipes', pathMatch: 'full' }, | ||||
| @@ -15,7 +17,9 @@ const appRoutes: Routes = [ | |||||
| { path: ':id', component: RecipeDetailComponent }, | { path: ':id', component: RecipeDetailComponent }, | ||||
| { path: ':id/edit', component: RecipeEditComponent} | { path: ':id/edit', component: RecipeEditComponent} | ||||
| ] }, | ] }, | ||||
| { path: 'shopping-list', component: ShoppingListComponent } | |||||
| { path: 'shopping-list', component: ShoppingListComponent }, | |||||
| { path: 'signup', component: SignupComponent }, | |||||
| { path: 'signin', component: SigninComponent } | |||||
| ]; | ]; | ||||
| @NgModule({ | @NgModule({ | ||||
| @@ -1,13 +1,21 @@ | |||||
| import { Component } from '@angular/core'; | |||||
| import { Component, OnInit } from '@angular/core'; | |||||
| import * as firebase from 'firebase'; | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-root', | selector: 'app-root', | ||||
| templateUrl: './app.component.html', | templateUrl: './app.component.html', | ||||
| styleUrls: ['./app.component.css'] | styleUrls: ['./app.component.css'] | ||||
| }) | }) | ||||
| export class AppComponent { | |||||
| export class AppComponent implements OnInit { | |||||
| loadedFeature = 'recipe'; | loadedFeature = 'recipe'; | ||||
| ngOnInit() { | |||||
| firebase.initializeApp({ | |||||
| apiKey: "AIzaSyB_-OMDNvUHDfSOzbpW8uHIxlTF8CaZHZo", | |||||
| authDomain: "my-recipe-book-cb837.firebaseapp.com" | |||||
| }); | |||||
| } | |||||
| onNavigate(feature: string) { | onNavigate(feature: string) { | ||||
| this.loadedFeature = feature; | 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 { RecipeEditComponent } from './recipes/recipe-edit/recipe-edit.component'; | ||||
| import { RecipeService } from './recipes/recipe.service'; | import { RecipeService } from './recipes/recipe.service'; | ||||
| import { DataStorageService } from './shared/data-storage.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({ | @NgModule({ | ||||
| @@ -34,7 +37,9 @@ import { DataStorageService } from './shared/data-storage.service'; | |||||
| ShoppingEditComponent, | ShoppingEditComponent, | ||||
| DropdownDirective, | DropdownDirective, | ||||
| RecipeStartComponent, | RecipeStartComponent, | ||||
| RecipeEditComponent | |||||
| RecipeEditComponent, | |||||
| SignupComponent, | |||||
| SigninComponent | |||||
| ], | ], | ||||
| imports: [ | imports: [ | ||||
| BrowserModule, | BrowserModule, | ||||
| @@ -44,7 +49,7 @@ import { DataStorageService } from './shared/data-storage.service'; | |||||
| HttpModule, | HttpModule, | ||||
| AppRoutingModule | AppRoutingModule | ||||
| ], | ], | ||||
| providers: [ShoppingListService, RecipeService, DataStorageService], | |||||
| providers: [ShoppingListService, RecipeService, DataStorageService, AuthService], | |||||
| bootstrap: [AppComponent] | bootstrap: [AppComponent] | ||||
| }) | }) | ||||
| export class AppModule { } | 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> | <li routerLinkActive="active"><a routerLink="/shopping-list">Shopping List</a></li> | ||||
| </ul> | </ul> | ||||
| <ul class="nav navbar-nav navbar-right"> | <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> | <li class="dropdown" appDropdown> | ||||
| <a style="cursor: pointer;" class="dropdown-toggle" role="button">Manage <span class="caret"></span></a> | <a style="cursor: pointer;" class="dropdown-toggle" role="button">Manage <span class="caret"></span></a> | ||||
| <ul class="dropdown-menu"> | <ul class="dropdown-menu"> | ||||