Skip to content

Commit 6103dfb

Browse files
author
Ihor Khomiak
committed
implement firebase login/register/logout functionality; implement validation in login and registration views
1 parent cb1069d commit 6103dfb

File tree

10 files changed

+204
-85
lines changed

10 files changed

+204
-85
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ app/cost/*.js
1010
app/tns_modules/
1111

1212
.idea/
13-
mkmf.log
13+
mkmf.log
14+
*.json

app/app.module.ts

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,22 @@
1-
import { NgModule, NO_ERRORS_SCHEMA } from "@angular/core";
2-
import { NativeScriptModule } from "nativescript-angular/nativescript.module";
1+
import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
2+
import { NativeScriptModule } from 'nativescript-angular/nativescript.module';
3+
import { NativeScriptFormsModule } from "nativescript-angular/forms"
34

4-
import { AppRoutingModule } from "./app.routing";
5-
import { AppComponent } from "./app.component";
6-
import { CostModule } from "./tabs/cost/cost.module";
7-
import { CalendarModule } from "./tabs/calendar/calendar.module"
8-
import { BudgetModule } from "./budget/budget.module";
9-
10-
11-
import { TabsComponent } from "./tabs/tabs.component";
12-
import { CostsComponent } from "./tabs/cost/costs.component";
13-
import { LoginComponent} from "./login/login.component";
14-
import { RegisterComponent} from "./register/register.component";
15-
import { CalendarComponent} from "./tabs/calendar/calendar.component";
16-
17-
import { CalendarDateRangeComponent } from "./tabs/calendar/date-range/calendar-date-range.component";
18-
import { CalendarDateRangeCostListComponent } from "./tabs/calendar/date-range-cost-list/calendar-date-range-cost-list.component";
19-
import { ListComponent } from "./list/list.component";
20-
import { ChartComponent } from "./tabs/charts/chart.component";
21-
import { BudgetComponent } from "./budget/budget.component";
5+
import { AppComponent } from './app.component';
6+
import { AppRoutingModule } from './app.routing';
7+
import { BudgetComponent } from './budget/budget.component';
8+
import { BudgetModule } from './budget/budget.module';
9+
import { ListComponent } from './list/list.component';
10+
import { LoginComponent } from './login/login.component';
11+
import { RegisterComponent } from './register/register.component';
12+
import { CalendarComponent } from './tabs/calendar/calendar.component';
13+
import { CalendarModule } from './tabs/calendar/calendar.module';
14+
import { CalendarDateRangeCostListComponent } from './tabs/calendar/date-range-cost-list/calendar-date-range-cost-list.component';
15+
import { CalendarDateRangeComponent } from './tabs/calendar/date-range/calendar-date-range.component';
16+
import { ChartComponent } from './tabs/charts/chart.component';
17+
import { CostModule } from './tabs/cost/cost.module';
18+
import { CostsComponent } from './tabs/cost/costs.component';
19+
import { TabsComponent } from './tabs/tabs.component';
2220

2321
@NgModule({
2422
bootstrap: [
@@ -27,6 +25,7 @@ import { BudgetComponent } from "./budget/budget.component";
2725
imports: [
2826
NativeScriptModule,
2927
AppRoutingModule,
28+
NativeScriptFormsModule,
3029
CostModule,
3130
CalendarModule,
3231
BudgetModule

app/common/protocol.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,15 @@
11
export interface DateRange {
22
startDate: string;
33
endDate: string;
4+
}
5+
6+
export interface User {
7+
uid: string;
8+
name: string;
9+
email: string;
10+
emailVerified: boolean;
11+
providers: any[];
12+
anonymous: boolean;
13+
phoneNumber: string;
14+
profileImageURL: string;
415
}

app/login/login.component.html

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,41 @@
1-
<ActionBar title="Money Tracker "
1+
<ActionBar title="Money Tracker"
22
class="action-bar">
33
</ActionBar>
44

55
<StackLayout verticalAlignment="center"
66
class="container">
7+
<ActivityIndicator [busy]="isLoading"
8+
[visibility]="isLoading ? 'visible' : 'collapse'"
9+
horizontalAlignment="center"
10+
verticalAlignment="center"></ActivityIndicator>
711
<StackLayout class="group">
8-
<Label text="Email"
9-
class="label font-weight-bold m-b-5"></Label>
10-
<TextField keyboardType="email"
11-
autocorrect="false"></TextField>
12+
<TextField #email="ngModel"
13+
[(ngModel)]="form.email"
14+
hint="Email"
15+
keyboardType="email"
16+
autocorrect="false"
17+
minlength="1"
18+
required></TextField>
19+
<StackLayout *ngIf="email.errors && email.dirty && email.touched">
20+
<Label *ngIf="email.errors.required"
21+
text="- An email field is required -"></Label>
22+
<Label *ngIf="email.errors.minlength"
23+
text="- Email must be longer than 1 characters -"></Label>
24+
</StackLayout>
1225
</StackLayout>
1326
<StackLayout class="group">
14-
<Label text="Password"
15-
class="label font-weight-bold m-b-5"></Label>
16-
<TextField secure="true"></TextField>
27+
<TextField #password="ngModel"
28+
[(ngModel)]="form.password"
29+
secure="true"
30+
hint="Password"
31+
minlength="1"
32+
required></TextField>
33+
<StackLayout *ngIf="password.errors && password.dirty && password.touched">
34+
<Label *ngIf="password.errors.required"
35+
text="- A password is required -"></Label>
36+
<Label *ngIf="password.errors.minlength"
37+
text="- Password must be longer than 1 characters -"></Label>
38+
</StackLayout>
1739
</StackLayout>
1840
<StackLayout class="group">
1941
<Button text="Login"

app/login/login.component.ts

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,55 @@
1-
import { Component, OnInit } from "@angular/core";
2-
import { RouterExtensions } from "nativescript-angular/router";
3-
import * as ApplicationSettings from "application-settings";
1+
import { Component } from '@angular/core';
2+
import { RouterExtensions } from 'nativescript-angular/router';
3+
import firebase = require('nativescript-plugin-firebase');
4+
5+
import { User } from '../common/protocol';
6+
47

58
@Component({
69
moduleId: module.id,
7-
selector: "ns-login",
10+
selector: "login",
811
templateUrl: "login.component.html",
912
styleUrls: ["login.component.css"]
1013
})
11-
export class LoginComponent implements OnInit {
12-
13-
public input: any;
14-
14+
export class LoginComponent {
15+
private user: User;
16+
private form: any = {};
17+
private isLoading: boolean = false;
18+
1519
public constructor(private router: RouterExtensions) {
16-
this.input = {
17-
"email": "",
18-
"password": ""
19-
}
2020
}
21-
22-
public ngOnInit() {}
23-
24-
public login() {
25-
this.router.navigate(["/tabs"], { clearHistory: true });
21+
22+
ngOnInit() {
23+
this.autoLogin();
24+
}
25+
26+
private login() {
27+
this.isLoading = true;
28+
firebase.login({
29+
type: firebase.LoginType.PASSWORD,
30+
email: this.form.email, // '[email protected]',
31+
password: this.form.password // '123456'
32+
})
33+
.then((user) => {
34+
this.isLoading = false;
35+
this.user = user as User;
36+
alert("Logged in as " + user['email']);
37+
this.router.navigate(["/tabs"], { clearHistory: true });
38+
}, (error) => {
39+
this.isLoading = false;
40+
alert("Error: " + error);
41+
});
42+
}
43+
44+
private autoLogin() {
45+
// to immediately re-login the user when he re-visits app
46+
const that = this;
47+
firebase.init({
48+
onAuthStateChanged: function(data) {
49+
if (data.loggedIn) {
50+
that.router.navigate(["/tabs"], { clearHistory: true })
51+
}
52+
}
53+
});
2654
}
2755
}

app/register/register.component.html

Lines changed: 47 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,51 @@
33
</ActionBar>
44

55
<StackLayout verticalAlignment="center"
6-
class="container" >
7-
<Label text="Name"
8-
class="label font-weight-bold m-b-5"></Label>
9-
<TextField></TextField>
10-
<Label text="Surname"
11-
class="label font-weight-bold m-b-5"></Label>
12-
<TextField></TextField>
13-
<Label text="Login"
14-
class="label font-weight-bold m-b-5"></Label>
15-
<TextField></TextField>
16-
<Label text="Email"
17-
class="label font-weight-bold m-b-5"></Label>
18-
<TextField></TextField>
19-
<Label text="Password"
20-
class="label font-weight-bold m-b-5"></Label>
21-
<TextField secure="true"></TextField>
22-
<Button [nsRouterLink]="['']"
23-
text="Register"
24-
class="btn-register"></Button>
6+
class="container">
7+
<ActivityIndicator [busy]="isLoading"
8+
[visibility]="isLoading ? 'visible' : 'collapse'"
9+
horizontalAlignment="center"
10+
verticalAlignment="center"></ActivityIndicator>
11+
<TextField [(ngModel)]="form.email"
12+
#email="ngModel"
13+
hint="Email"
14+
keyboardType="email"
15+
autocorrect="false"
16+
minlength="1"
17+
required></TextField>
18+
<StackLayout *ngIf="email.errors && email.dirty && email.touched">
19+
<Label *ngIf="email.errors.required"
20+
text="- An email field is required -"></Label>
21+
<Label *ngIf="email.errors.minlength"
22+
text="- Email must be longer than 1 characters -"></Label>
23+
</StackLayout>
24+
<TextField [(ngModel)]="form.name"
25+
#name="ngModel"
26+
hint="Name"
27+
autocorrect="false"
28+
minlength="1"
29+
required></TextField>
30+
<StackLayout *ngIf="name.errors && name.dirty && name.touched">
31+
<Label *ngIf="name.errors.required"
32+
text="- An name field is required -"></Label>
33+
<Label *ngIf="name.errors.minlength"
34+
text="- Name field must be longer than 1 characters -"></Label>
35+
</StackLayout>
36+
<TextField [(ngModel)]="form.password"
37+
#password="ngModel"
38+
hint="Password"
39+
secure="true"
40+
hint="Password"
41+
minlength="1"
42+
required></TextField>
43+
<StackLayout *ngIf="password.errors && password.dirty && password.touched">
44+
<Label *ngIf="password.errors.required"
45+
text="- An password field is required -"></Label>
46+
<Label *ngIf="password.errors.minlength"
47+
text="- Password field must be longer than 1 characters -"></Label>
48+
</StackLayout>
49+
<Button [nsRouterLink]="['']"
50+
text="Register"
51+
(tap)="onRegister()"
52+
class="btn-register"></Button>
2553
</StackLayout>

app/register/register.component.ts

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,37 @@
1-
import { Component, OnInit } from "@angular/core";
2-
import { RouterExtensions } from "nativescript-angular/router";
3-
import * as ApplicationSettings from "application-settings";
1+
import { Component } from '@angular/core';
2+
import { RouterExtensions } from 'nativescript-angular/router';
3+
import firebase = require('nativescript-plugin-firebase');
4+
5+
import { User } from '../common/protocol';
46

57
@Component({
68
moduleId: module.id,
7-
selector: "ns-register",
9+
selector: "register",
810
templateUrl: "register.component.html",
911
styleUrls: ["register.component.css"]
1012
})
11-
export class RegisterComponent implements OnInit {
13+
export class RegisterComponent {
14+
private form: any = {};
15+
private isLoading: boolean = false;
1216

13-
public input: any;
14-
1517
public constructor(private router: RouterExtensions) {
16-
this.input = {
17-
"name": "",
18-
"surname": "",
19-
"login": "",
20-
"email": "",
21-
"password": "",
22-
}
2318
}
2419

25-
public ngOnInit() {}
20+
public onRegister() {
21+
this.isLoading = true;
22+
firebase.createUser({
23+
email: this.form.email, // '[email protected]',
24+
password: this.form.password // '123456'
25+
})
26+
.then(
27+
(user) =>{
28+
this.isLoading = false;
29+
alert("Created new user!");
30+
},
31+
(error) => {
32+
this.isLoading = false;
33+
alert("Error: " + error);
34+
}
35+
);
36+
}
2637
}

app/tabs/cost/costs.component.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
<ActionBar title="Last Costs"
22
class="action-bar">
3+
<ActionItem android.position="right"
4+
(tap)="logout()">
5+
<Label text="Logout"
6+
class="action-item"></Label>
7+
</ActionItem>
38
</ActionBar>
49

510
<StackLayout class="page"

app/tabs/cost/costs.component.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
import { Component, OnInit, ViewChild, ElementRef } from "@angular/core";
2-
import { TextField } from "ui/text-field";
1+
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
2+
import { TextField } from 'ui/text-field';
3+
import { RouterExtensions } from 'nativescript-angular/router';
34

4-
import { Cost } from "./cost";
5-
import { CostService } from "./cost.service";
5+
import { Cost } from './cost';
6+
import { CostService } from './cost.service';
7+
8+
import firebase = require('nativescript-plugin-firebase');
69

710
@Component({
811
selector: "costs",
@@ -14,7 +17,7 @@ export class CostsComponent implements OnInit {
1417

1518
@ViewChild("newCostTextField") newCostTextField: ElementRef;
1619

17-
constructor(private costService: CostService) { }
20+
constructor(private router: RouterExtensions, private costService: CostService) { }
1821

1922
ngOnInit(): void {
2023
// this.costService.costsListObservable.subscribe((costs) => {
@@ -43,4 +46,14 @@ export class CostsComponent implements OnInit {
4346
this.costService.addCost(cost);
4447
textField.text = "";
4548
}
49+
50+
logout() {
51+
firebase.logout()
52+
.then(() => {
53+
alert("Logged out successfully!");
54+
this.router.navigate([""], { clearHistory: true });
55+
}, (error) => {
56+
alert("Error: " + error);
57+
});
58+
}
4659
}

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"@angular/platform-browser": "~4.1.0",
2323
"@angular/router": "~4.1.0",
2424
"nativescript-angular": "~3.1.0",
25+
"nativescript-plugin-firebase": "^5.1.4",
2526
"nativescript-theme-core": "~1.0.2",
2627
"reflect-metadata": "~0.1.8",
2728
"rxjs": "~5.3.0",

0 commit comments

Comments
 (0)