From 72303335a13bf01ac41681eb567bc4d27d47ac1a Mon Sep 17 00:00:00 2001 From: ztimson Date: Sun, 21 Apr 2019 19:33:50 -0400 Subject: [PATCH] Added admin page --- src/app/admin/admin.component.html | 58 +++++++++++++++++++ src/app/admin/admin.component.ts | 11 ++++ src/app/admin/admin.service.ts | 15 +++++ src/app/app.component.html | 9 +++ src/app/app.component.ts | 9 +++ src/app/app.module.ts | 4 ++ src/app/app.routing.ts | 3 + src/app/app.store.ts | 12 +++- src/app/auth.service.ts | 41 +++++++++++++ .../typewriter/typewriter.component.ts | 4 +- src/app/home/home.component.html | 3 +- src/app/models/dbUser.ts | 6 ++ src/app/models/user.ts | 4 ++ 13 files changed, 174 insertions(+), 5 deletions(-) create mode 100644 src/app/admin/admin.component.html create mode 100644 src/app/admin/admin.component.ts create mode 100644 src/app/admin/admin.service.ts create mode 100644 src/app/auth.service.ts create mode 100644 src/app/models/dbUser.ts create mode 100644 src/app/models/user.ts diff --git a/src/app/admin/admin.component.html b/src/app/admin/admin.component.html new file mode 100644 index 0000000..670db95 --- /dev/null +++ b/src/app/admin/admin.component.html @@ -0,0 +1,58 @@ +
+
+
+ +
+
+
+
+

Users

+ + + + + + + + + + + + + + + + + +
First NameLast NameEmailAdmin
{{user.firstName}}{{user.lastName}}{{user.email}} +
+ +
+
+
+
+

Quotes

+ + + + + + + + + + + + + + +
Quote
{{quote.text}}
+ + Add Quote +
+
+
+ © 2019 ZaksCode +
+
+
diff --git a/src/app/admin/admin.component.ts b/src/app/admin/admin.component.ts new file mode 100644 index 0000000..e466d93 --- /dev/null +++ b/src/app/admin/admin.component.ts @@ -0,0 +1,11 @@ +import {Component} from '@angular/core'; +import {AdminService} from './admin.service'; +import {AppStore} from '../app.store'; + +@Component({ + selector: 'admin', + templateUrl: 'admin.component.html' +}) +export class AdminComponent { + constructor(public adminService: AdminService, public store: AppStore) {} +} diff --git a/src/app/admin/admin.service.ts b/src/app/admin/admin.service.ts new file mode 100644 index 0000000..108244c --- /dev/null +++ b/src/app/admin/admin.service.ts @@ -0,0 +1,15 @@ +import {Observable} from 'rxjs'; +import {DbUser} from '../models/dbUser'; +import {AngularFirestore} from '@angular/fire/firestore'; +import {Injectable} from '@angular/core'; + +@Injectable({ + providedIn: 'root' +}) +export class AdminService { + users: Observable; + + constructor(private firestore: AngularFirestore) { + this.users = this.firestore.collection('users').valueChanges(); + } +} diff --git a/src/app/app.component.html b/src/app/app.component.html index 0680b43..7a96c37 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1 +1,10 @@ +
+
+ Admin Panel + Logout +
+
+ Login +
+
diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 7969739..d657cbe 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,11 +1,20 @@ import {Component} from '@angular/core'; +import {AuthService} from './auth.service'; +import {ActivatedRoute} from '@angular/router'; @Component({ selector: 'app-root', templateUrl: 'app.component.html' }) export class AppComponent { + loggedIn = false; + set title(title: string) { document.getElementsByTagName('title')[0].innerHTML = `Zaks Code${title ? ` - ${title}` : ''}`; } + + constructor(private route: ActivatedRoute, public authService: AuthService) { + this.route.url.subscribe(() => this.title = ''); // Clear the title on nav event + this.authService.user.subscribe(user => this.loggedIn = !!user); + } } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index ac76c67..6e3513d 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -12,15 +12,19 @@ import {SlideShowComponent} from './components/slideShow/slideShow.component'; import {environment} from '../environments/environment'; import {AppComponent} from './app.component'; import {AppRouting} from './app.routing'; +import {AdminComponent} from './admin/admin.component'; +import {AngularFireAuthModule} from '@angular/fire/auth'; @NgModule({ declarations: [ + AdminComponent, AppComponent, HomeComponent, SlideShowComponent, TypewriterComponent ], imports: [ + AngularFireAuthModule, AngularFireModule.initializeApp(environment.firebase), AngularFirestoreModule, AppRouting, diff --git a/src/app/app.routing.ts b/src/app/app.routing.ts index fcdc5f9..4edbf64 100644 --- a/src/app/app.routing.ts +++ b/src/app/app.routing.ts @@ -1,11 +1,14 @@ import {NgModule} from '@angular/core'; import {RouterModule} from '@angular/router'; import {HomeComponent} from './home/home.component'; +import {AdminComponent} from './admin/admin.component'; +import {AuthService} from './auth.service'; @NgModule({ imports: [ RouterModule.forRoot([ {path: '', component: HomeComponent}, + {path: 'admin', component: AdminComponent, canActivate: [AuthService]}, {path: '**', redirectTo: ''} ]) ], diff --git a/src/app/app.store.ts b/src/app/app.store.ts index 2a224ff..652ebb1 100644 --- a/src/app/app.store.ts +++ b/src/app/app.store.ts @@ -1,7 +1,8 @@ import {Injectable} from '@angular/core'; -import {Observable} from 'rxjs'; +import {BehaviorSubject, Observable} from 'rxjs'; import {AngularFirestore} from '@angular/fire/firestore'; import {Quote} from './models/quote'; +import {DbUser} from './models/dbUser'; @Injectable({ providedIn: 'root' @@ -12,4 +13,13 @@ export class AppStore { constructor(private firestore: AngularFirestore) { this.quotes = this.firestore.collection('quotes').valueChanges(); } + + addQuote(text: string) { + return this.firestore.collection('quotes').add({text: text}); + } + + async getUser(uid: string) { + let user = await this.firestore.collection('users').doc(uid).get().toPromise(); + return user.data(); + } } diff --git a/src/app/auth.service.ts b/src/app/auth.service.ts new file mode 100644 index 0000000..781c3fe --- /dev/null +++ b/src/app/auth.service.ts @@ -0,0 +1,41 @@ +import {Injectable} from '@angular/core'; +import {AngularFireAuth} from '@angular/fire/auth'; +import {CanActivate, Router} from '@angular/router'; +import {BehaviorSubject, Observable} from 'rxjs'; +import { auth } from 'firebase'; + +import {map} from 'rxjs/operators'; +import {User} from './models/user'; +import {AppStore} from './app.store'; +import {tap} from 'rxjs/internal/operators/tap'; +import {filter} from 'rxjs/internal/operators/filter'; + +@Injectable({ + providedIn: 'root' +}) +export class AuthService implements CanActivate { + user = new BehaviorSubject(null); + + constructor(private store: AppStore, private afAuth: AngularFireAuth, private router: Router) { + this.afAuth.user.subscribe(async user => { + this.user.next(user ? Object.assign(await this.store.getUser(user.uid), user): null); + }); + } + + canActivate(): Observable { + return this.user.pipe( + filter(user => !!user), + map(user => !user.isAnonymous), + tap(user => user ? null : this.googleLogin()) + ); + } + + googleLogin() { + return this.afAuth.auth.signInWithPopup(new auth.GoogleAuthProvider()); + } + + async logout() { + await this.afAuth.auth.signOut(); + this.router.navigate(['/']); + } +} diff --git a/src/app/components/typewriter/typewriter.component.ts b/src/app/components/typewriter/typewriter.component.ts index c8982a6..564603c 100644 --- a/src/app/components/typewriter/typewriter.component.ts +++ b/src/app/components/typewriter/typewriter.component.ts @@ -9,8 +9,8 @@ import {filter, map} from 'rxjs/operators'; styleUrls: ['typewriter.component.scss'] }) export class TypewriterComponent { - readonly delay = 1500; - readonly speed = 100; + @Input() delay = 1500; + @Input() speed = 100; @Input() set text(text: string) { diff --git a/src/app/home/home.component.html b/src/app/home/home.component.html index 9ee2feb..829753e 100644 --- a/src/app/home/home.component.html +++ b/src/app/home/home.component.html @@ -18,8 +18,7 @@
London Ontario, Canada
- + diff --git a/src/app/models/dbUser.ts b/src/app/models/dbUser.ts new file mode 100644 index 0000000..62700ec --- /dev/null +++ b/src/app/models/dbUser.ts @@ -0,0 +1,6 @@ +export interface DbUser { + admin: boolean; + email: string; + firstName: string; + lastName: string; +} diff --git a/src/app/models/user.ts b/src/app/models/user.ts new file mode 100644 index 0000000..63fdecf --- /dev/null +++ b/src/app/models/user.ts @@ -0,0 +1,4 @@ +import {User as FirebaseUser} from 'firebase'; +import {DbUser} from './dbUser'; + +export interface User extends FirebaseUser, DbUser { }