Skip to content

Commit 31e3d5c

Browse files
committed
CRUD personal books using firebase database and authentication services
1 parent bf0f9a0 commit 31e3d5c

22 files changed

+2040
-1036
lines changed

README.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,22 @@ A simple application that lists the books you have at home, in your library. You
55
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 9.1.5.
66

77
## Prerequisites
8+
To be able to run this application, you need these dependencies
89

9-
- nodejs
10+
- nodejs >=v10.13
1011
- npm package manager
1112

12-
Then you should install `Angular CLI` if it's not already exists.
13+
Then install Angular CLI `npm install @angular/cli@9.1.5` (add `-g` option if you want install Angular CLI globally).
1314

1415
## Running application
1516

16-
1. Clone this repository : `https://github.com/masteropen/angular-personal-books-manager.git`.
17+
1. Clone this repository : `git clone https://github.com/masteropen/angular-personal-books-manager.git`
1718

18-
2. `cd angular-personal-books-manager` and run `ng serve` for a dev server.
19+
2. Install dependencies `npm install`
20+
21+
3. Run Angular built-in dev server `ng serve`
1922

20-
3. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
23+
4. Navigate to `http://localhost:4200`. The app will automatically reload if you change any of the source files.
2124

2225
## Running unit tests
2326

package-lock.json

Lines changed: 1507 additions & 984 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020
"@angular/platform-browser-dynamic": "~9.1.6",
2121
"@angular/router": "~9.1.6",
2222
"bootstrap": "^3.3.7",
23+
"firebase": "^7.14.4",
2324
"rxjs": "~6.5.4",
25+
"rxjs-compat": "^6.5.5",
2426
"tslib": "^1.10.0",
2527
"zone.js": "~0.10.2"
2628
},

src/app/app.component.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Component } from '@angular/core';
2+
import * as firebase from 'firebase';
23

34
@Component({
45
selector: 'app-root',
@@ -7,4 +8,17 @@ import { Component } from '@angular/core';
78
})
89
export class AppComponent {
910
title = 'my-books-manager';
11+
constructor() {
12+
const config = {
13+
apiKey: "AIzaSyA5fQPALCwF-3AhsSLMgkSMBLquioD4eA0",
14+
authDomain: "angular-personal-books.firebaseapp.com",
15+
databaseURL: "https://angular-personal-books.firebaseio.com",
16+
projectId: "angular-personal-books",
17+
storageBucket: "angular-personal-books.appspot.com",
18+
messagingSenderId: "48853693820",
19+
appId: "1:48853693820:web:9b9a1d0c7615003114e0f9"
20+
}
21+
22+
firebase.initializeApp(config);
23+
}
1024
}

src/app/app.module.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,18 @@ import { HeaderComponent } from './header/header.component';
1111
import { AuthService } from './services/auth.service';
1212
import { AuthGuardService } from './services/auth-guard.service';
1313
import { BooksService } from './services/books.service';
14-
import {RouterModule, Routes} from '@angular/router';
14+
import { RouterModule, Routes } from '@angular/router';
1515
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
1616
import { HttpClientModule } from '@angular/common/http';
1717

1818
const appRoutes: Routes = [
1919
{ path: 'auth/signup', component: SignupComponent },
2020
{ path: 'auth/signin', component: SigninComponent },
21-
{ path: 'books', component: BookListComponent },
22-
{ path: 'books/new', component: BookFormComponent },
23-
{ path: 'books/view/:id', component: SingleBookComponent }
21+
{ path: 'books', component: BookListComponent, canActivate: [AuthGuardService] },
22+
{ path: 'books/new', component: BookFormComponent, canActivate: [AuthGuardService] },
23+
{ path: 'books/view/:id', component: SingleBookComponent, canActivate: [AuthGuardService] },
24+
{ path: '', redirectTo: 'books', pathMatch: 'full' },
25+
{ path: '**', redirectTo: 'books' }
2426
];
2527

2628
@NgModule({
@@ -31,7 +33,7 @@ const appRoutes: Routes = [
3133
BookListComponent,
3234
SingleBookComponent,
3335
BookFormComponent,
34-
HeaderComponent
36+
HeaderComponent,
3537
],
3638
imports: [
3739
BrowserModule,
Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,25 @@
1-
<p>signin works!</p>
1+
<div class="row">
2+
<div class="col-sm-8 col-sm-offset-2">
3+
<h2>Connexion</h2>
4+
<form [formGroup]="signinForm" (ngSubmit)="onSubmit()">
5+
<div class="form-group">
6+
<label for="email">Adresse mail</label>
7+
<input type="text"
8+
id="email"
9+
class="form-control"
10+
formControlName="email">
11+
</div>
12+
<div class="form-group">
13+
<label for="password">Mot de passe</label>
14+
<input type="password"
15+
id="password"
16+
class="form-control"
17+
formControlName="password">
18+
</div>
19+
<button class="btn btn-primary"
20+
type="submit"
21+
[disabled]="signinForm.invalid">Se connecter</button>
22+
</form>
23+
<p class="text-danger">{{ errorMessage }}</p>
24+
</div>
25+
</div>
Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
import { Component, OnInit } from '@angular/core';
2+
import {FormBuilder, FormGroup, Validators} from "@angular/forms";
3+
import { AuthService } from "../../services/auth.service";
4+
import {Router} from '@angular/router';
25

36
@Component({
47
selector: 'app-signin',
@@ -7,9 +10,35 @@ import { Component, OnInit } from '@angular/core';
710
})
811
export class SigninComponent implements OnInit {
912

10-
constructor() { }
13+
errorMessage: string;
14+
signinForm: FormGroup;
15+
16+
constructor(private formBuilder:FormBuilder,
17+
private authService: AuthService,
18+
private router: Router) { }
1119

1220
ngOnInit(): void {
21+
this.initForm();
22+
}
23+
24+
initForm() {
25+
this.signinForm = this.formBuilder.group({
26+
email: ['', [Validators.required, Validators.email]],
27+
password: ['', Validators.required],
28+
});
1329
}
1430

31+
onSubmit() {
32+
const email = this.signinForm.value['email'];
33+
const password = this.signinForm.value['password'];
34+
35+
this.authService.signInUser(email, password).then(
36+
() => {
37+
this.router.navigate(['/books'])
38+
},
39+
(error) => {
40+
this.errorMessage = error;
41+
}
42+
);
43+
}
1544
}
Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,25 @@
1-
<p>signup works!</p>
1+
<div class="row">
2+
<div class="col-sm-8 col-sm-offset-2">
3+
<h2>Créer un compte</h2>
4+
<form [formGroup]="signupForm" (ngSubmit)="onSubmit()">
5+
<div class="form-group">
6+
<label for="email">Adresse mail</label>
7+
<input type="text"
8+
id="email"
9+
class="form-control"
10+
formControlName="email">
11+
</div>
12+
<div class="form-group">
13+
<label for="password">Mot de passe</label>
14+
<input type="password"
15+
id="password"
16+
class="form-control"
17+
formControlName="password">
18+
</div>
19+
<button class="btn btn-primary"
20+
type="submit"
21+
[disabled]="signupForm.invalid">Créer mon compte</button>
22+
</form>
23+
<p class="text-danger">{{ errorMessage }}</p>
24+
</div>
25+
</div>
Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
import { Component, OnInit } from '@angular/core';
2+
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
3+
import { AuthService } from '../../services/auth.service';
4+
import { Router } from '@angular/router';
25

36
@Component({
47
selector: 'app-signup',
@@ -7,9 +10,35 @@ import { Component, OnInit } from '@angular/core';
710
})
811
export class SignupComponent implements OnInit {
912

10-
constructor() { }
13+
signupForm: FormGroup;
14+
errorMessage: string;
1115

12-
ngOnInit(): void {
16+
constructor(private formBuilder: FormBuilder,
17+
private authService: AuthService,
18+
private router: Router) { }
19+
20+
ngOnInit() {
21+
this.initForm();
22+
}
23+
24+
initForm() {
25+
this.signupForm = this.formBuilder.group({
26+
email: ['', [Validators.required, Validators.email]],
27+
password: ['', [Validators.required, Validators.pattern(/[0-9a-zA-Z]{6,}/)]] // accept at least 6 alpha-numeric character
28+
});
1329
}
1430

31+
onSubmit() {
32+
const email = this.signupForm.get('email').value;
33+
const password = this.signupForm.get('password').value;
34+
35+
this.authService.createNewUser(email, password).then(
36+
() => {
37+
this.router.navigate(['/books']);
38+
},
39+
(error) => {
40+
this.errorMessage = error;
41+
}
42+
);
43+
}
1544
}
Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,27 @@
1-
<p>book-form works!</p>
1+
<div class="row">
2+
<div class="col-sm-8 col-sm-offset-2">
3+
<h2>Enregistrer un nouveau livre</h2>
4+
<form [formGroup]="bookForm" (ngSubmit)="onSaveBook()">
5+
<div class="form-group">
6+
<label for="title">Titre</label>
7+
<input type="text" id="title"
8+
class="form-control" formControlName="title">
9+
</div>
10+
<div class="form-group">
11+
<label for="author">Auteur</label>
12+
<input type="text" id="author"
13+
class="form-control" formControlName="author">
14+
</div>
15+
<div class="form-group">
16+
<label for="synopsis">Synopsis</label>
17+
<textarea id="synopsis"
18+
class="form-control" formControlName="synopsis">
19+
</textarea>
20+
</div>
21+
<button class="btn btn-success" [disabled]="bookForm.invalid"
22+
type="submit">Enregistrer
23+
</button>
24+
25+
</form>
26+
</div>
27+
</div>

0 commit comments

Comments
 (0)