This repository has been archived by the owner on Dec 12, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
0afd0c3
commit 85b7d20
Showing
15 changed files
with
396 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
<section class="red"> | ||
<div class="container width"> | ||
<div class="one unit row"> | ||
<h1>Sponsorship Portal Admin</h1> | ||
</div> | ||
<div class="one unit row"> | ||
<h3>Manage sponsors' accounts.</h3> | ||
</div> | ||
</div> | ||
</section> | ||
|
||
<section> | ||
<div class="container width"> | ||
<div class="one unit row"> | ||
<h2>Sponsors</h2> | ||
</div> | ||
<div class="one unit row"> | ||
<h3>These sponsors are registered:</h3> | ||
</div> | ||
<div *ngFor="let sponsor of sponsors" class="half unit row"> | ||
<p> | ||
<a rel="next" [routerLink]="[ '/', sponsor.id ]">{{ sponsor.name }}</a> | ||
</p> | ||
</div> | ||
<div class="half unit row"> | ||
<p> | ||
<a [routerLink]="[ '/admin/new' ]">Add Sponsor</a> | ||
</p> | ||
</div> | ||
</div> | ||
</section> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { SponsorIndexModel } from 'app/admin/sponsor-index.model'; | ||
import { AdminService } from 'app/admin/admin.service'; | ||
import { Component } from '@angular/core'; | ||
|
||
@Component({ | ||
selector: 'app-admin', | ||
templateUrl: './admin.component.html' | ||
}) | ||
export class AdminComponent { | ||
sponsors: SponsorIndexModel[]; | ||
|
||
constructor(private adminService: AdminService) { | ||
adminService.getSponsors().subscribe( | ||
sponsors => this.sponsors = (sponsors ? sponsors : []) | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
import { Injectable } from '@angular/core'; | ||
import { AngularFireObject, AngularFireDatabase, AngularFireList } from 'angularfire2/database'; | ||
import { SponsorIndexModel } from 'app/admin/sponsor-index.model'; | ||
import { Observable } from 'rxjs/Observable'; | ||
import { SponsorshipBenefitModel } from 'app/benefits/sponsorship-benefit.model'; | ||
import { SponsorModel } from 'app/admin/sponsor.model'; | ||
import { UUID } from 'angular2-uuid'; | ||
import { SponsorsService } from 'app/sponsors/sponsors.service'; | ||
import { FirebaseApp } from 'angularfire2'; | ||
import { AngularFireAuth } from 'angularfire2/auth'; | ||
|
||
@Injectable() | ||
export class AdminService { | ||
constructor(private auth: AngularFireAuth, | ||
private db: AngularFireDatabase) {} | ||
|
||
loginUser(email: string, password: string): Promise<void> { | ||
return this.auth.auth.signInWithEmailAndPassword(email, password); | ||
} | ||
|
||
isLoggedIn(): Observable<boolean> { | ||
return this.auth.authState.map( | ||
user => user != null | ||
); | ||
} | ||
|
||
private getSponsorIndexObjects(): AngularFireObject<SponsorIndexModel[]> { | ||
return this.db.object('admin/sponsors'); | ||
} | ||
|
||
private getSponsorName(guid: string): AngularFireObject<string> { | ||
return this.db.object(`sponsors/${guid}/name`); | ||
} | ||
|
||
private getBenefitsObjects(): AngularFireObject<SponsorshipBenefitModel[]> { | ||
return this.db.object('benefits'); | ||
} | ||
|
||
private getSponsorObjects(): AngularFireList<SponsorModel> { | ||
return this.db.list('sponsors'); | ||
} | ||
|
||
getSponsors(): Observable<SponsorIndexModel[]> { | ||
return this.getSponsorIndexObjects().valueChanges(); | ||
} | ||
|
||
getBenefits(): Observable<SponsorshipBenefitModel[]> { | ||
return this.getBenefitsObjects().valueChanges(); | ||
} | ||
|
||
saveBenefits(benefits: SponsorshipBenefitModel[]): Promise<void> { | ||
return this.getBenefitsObjects().set(benefits); | ||
} | ||
|
||
addSponsor(sponsor: SponsorModel): Observable<string | void> { | ||
if (!(sponsor.benefits && sponsor.maxRecruiters && sponsor.name && sponsor.tier)) { | ||
return Observable.throw(new Error('Sponsor details not filled out')); | ||
} | ||
|
||
const guid$ = this.generateUniqueGuid().first(); | ||
|
||
return guid$.flatMap( | ||
guid => { | ||
const setSponsor = Observable.defer<void>(() => this.addSponsorObject(guid, sponsor)); | ||
const setIndex = Observable.defer(() => this.addSponsorIndex(guid, sponsor.name)); | ||
const setGuid = Observable.defer<string>(() => Observable.of(guid)); | ||
|
||
return Observable.concat(setSponsor, setIndex, setGuid); | ||
} | ||
); | ||
} | ||
|
||
private generateUniqueGuid(): Observable<string> { | ||
// Mae sure the GUID isn't already taken. | ||
const guid = UUID.UUID(); | ||
|
||
return this.getSponsorName(guid).valueChanges().first().flatMap( | ||
name => { | ||
if (name) { | ||
return this.generateUniqueGuid(); | ||
} | ||
else { | ||
return Observable.of(guid); | ||
} | ||
} | ||
); | ||
} | ||
|
||
private addSponsorObject(guid: string, sponsor: SponsorModel): Promise<void> { | ||
return this.db.object(`sponsors/${guid}`).set(sponsor); | ||
} | ||
|
||
private addSponsorIndex(guid: string, name: string): Observable<void> { | ||
const index: SponsorIndexModel = { | ||
id: guid, | ||
name: name | ||
}; | ||
|
||
const indexObjects = this.getSponsorIndexObjects(); | ||
|
||
return indexObjects.valueChanges().first().flatMap( | ||
(indices: SponsorIndexModel[]) => { | ||
indices.push(index); | ||
return indexObjects.set(indices); | ||
} | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export class SponsorIndexModel { | ||
id: string; | ||
name: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { SponsorshipTier } from 'app/sponsors/sponsorship-tier.enum'; | ||
import { SponsorshipBenefitModel } from 'app/benefits/sponsorship-benefit.model'; | ||
|
||
export class SponsorModel { | ||
name: string; | ||
tier: SponsorshipTier; | ||
maxRecruiters: number; | ||
benefits: SponsorshipBenefitModel[]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { CanActivate, CanActivateChild, Router } from '@angular/router'; | ||
import { AdminService } from 'app/admin/admin.service'; | ||
import { Injectable } from '@angular/core'; | ||
import { Observable } from 'rxjs/Observable'; | ||
|
||
@Injectable() | ||
export class AuthGuard implements CanActivate { | ||
constructor(private router: Router, | ||
private adminService: AdminService) { } | ||
|
||
canActivate(): Observable<boolean> { | ||
return this.adminService.isLoggedIn().map( | ||
loggedIn => { | ||
if (!loggedIn) { | ||
this.router.navigate(['/login']); | ||
} | ||
|
||
return loggedIn; | ||
} | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
import { SponsorBenefitTypes } from 'app/benefits/benefits.service'; | ||
|
||
export class SponsorshipBenefitModel { | ||
id: SponsorBenefitTypes; | ||
id: string; | ||
name: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<section class="red"> | ||
<div class="container width"> | ||
<div class="one unit row"> | ||
<h1>Login</h1> | ||
</div> | ||
<div class="one unit row"> | ||
<h3>Hack Cambridge Sponsorship Admin.</h3> | ||
</div> | ||
</div> | ||
</section> | ||
|
||
<section> | ||
<div class="container width"> | ||
<div class="one half unit row"> | ||
<div class="twelve unit column"> | ||
<fieldset> | ||
<input type="text" placeholder="Email" [(ngModel)]="email"> | ||
<input type="password" placeholder="Password" [(ngModel)]="password"> | ||
<input type="button" value="Login" (click)="login()"> | ||
</fieldset> | ||
</div> | ||
</div> | ||
</div> | ||
</section> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { AdminService } from 'app/admin/admin.service'; | ||
import { Router } from '@angular/router'; | ||
import { Component } from '@angular/core'; | ||
import { OnInit } from '@angular/core/src/metadata/lifecycle_hooks'; | ||
|
||
@Component({ | ||
selector: 'app-login', | ||
templateUrl: './login.component.html' | ||
}) | ||
export class LoginComponent implements OnInit { | ||
email: string; | ||
password: string; | ||
|
||
constructor(private adminService: AdminService, | ||
private router: Router) {} | ||
|
||
ngOnInit(): void { | ||
if (this.adminService.isLoggedIn()) { | ||
this.router.navigate([ '/admin' ]); | ||
} | ||
} | ||
|
||
login(): void { | ||
this.adminService.loginUser(this.email, this.password) | ||
.then(success => this.router.navigate([ '/admin' ])) | ||
.catch((error: Error) => { | ||
alert(error.message); | ||
}); | ||
} | ||
} |
Oops, something went wrong.