diff --git a/web/src/app/components/login-page/login-page.component.ts b/web/src/app/components/login-page/login-page.component.ts index b67eefc..40a476c 100644 --- a/web/src/app/components/login-page/login-page.component.ts +++ b/web/src/app/components/login-page/login-page.component.ts @@ -3,6 +3,7 @@ import { AuthService } from '../../services/auth.service'; import { UserService } from '../../services/user.service'; import { User } from '../../models/user.model'; import { UserSocial } from '../../models/userSocial.model'; +import { SocialStatsService } from 'src/app/services/social-stats.service'; @Component({ selector: 'app-login-page', @@ -14,6 +15,7 @@ export class LoginPageComponent implements OnInit { constructor( private authService: AuthService, private userService: UserService, + private socialStatsService: SocialStatsService, ) { } public hasError = false; @@ -52,13 +54,52 @@ export class LoginPageComponent implements OnInit { this.userService.saveUser(user) .subscribe((userData) => { this.saveUserSocialDetails(userData, provider); + this.saveUserSocialStats(userData, provider); }); } - saveUserSocialDetails(userData: User, provider: string) { + saveUserSocialStats(userData, provider: string) { + const socialStats = { ...userData, ...{ provider, createdAt: new Date().toISOString() } }; + this.socialStatsService.createSocialStats(socialStats) + .subscribe((response) => { + if (!response) { + console.error('error in storing stats history'); + } + }); + } + + saveUserSocialDetails(userData, provider: string) { const socialDetails = {}; socialDetails[provider] = userData; - this.userService.saveUserSocial(socialDetails) - .subscribe(); // TODO: Handle success and error scenarios after social doc changes. + this.userService.checkForSocialDoc(provider, userData.userId) + .subscribe((response) => { + if (!response) { + console.error('error in checking of existing social doc'); + return; + } + if (response.empty) { + this.createUserSocialDetails(socialDetails); + return; + } + this.updateUserSocialDetails(response.id, socialDetails); + }); + } + + createUserSocialDetails(socialDetails: UserSocial) { + this.userService.addSocialDoc(socialDetails) + .subscribe((response) => { + if (!response) { + console.error('error in creating social doc'); + } + }); + } + + updateUserSocialDetails(id: string, socialDetails: UserSocial) { + this.userService.updateSocialDoc(id, socialDetails) + .subscribe((response) => { + if (!response) { + console.error('error in updating user social doc'); + } + }); } } diff --git a/web/src/app/guards/auth.guard.ts b/web/src/app/guards/auth.guard.ts index d75112e..9dc806f 100644 --- a/web/src/app/guards/auth.guard.ts +++ b/web/src/app/guards/auth.guard.ts @@ -14,7 +14,6 @@ export class AuthGuardService implements CanActivate { ) { } canActivate(): Observable { - return this.auth.user.pipe( take(1), map(authUser => !!authUser), diff --git a/web/src/app/models/socialStatsHistory.ts b/web/src/app/models/socialStatsHistory.ts new file mode 100644 index 0000000..870f567 --- /dev/null +++ b/web/src/app/models/socialStatsHistory.ts @@ -0,0 +1,9 @@ +export interface SocialStatsHistory { + provider: string; + userId: string; + followers: number; + following: number; + repos?: number; + tweets?: number; + createdAt: string; +} diff --git a/web/src/app/models/userSocial.model.ts b/web/src/app/models/userSocial.model.ts index 4adfee9..0ffc540 100644 --- a/web/src/app/models/userSocial.model.ts +++ b/web/src/app/models/userSocial.model.ts @@ -1,8 +1,28 @@ import { Social } from './social.model'; export interface UserSocial { - github?: Social; - twitter?: Social; - youtube?: Social; - instagram?: Social; + github?: { + updatedAt: string, + followers: number, + following: number, + userId: string, + }; + twitter?: { + updatedAt: string, + followers: number, + following: number, + userId: string, + }; + youtube?: { + updatedAt: string, + followers: number, + following: number, + userId: string, + }; + instagram?: { + updatedAt: string, + followers: number, + following: number, + userId: string, + }; } diff --git a/web/src/app/services/auth.service.ts b/web/src/app/services/auth.service.ts index 621ad7e..a17c775 100644 --- a/web/src/app/services/auth.service.ts +++ b/web/src/app/services/auth.service.ts @@ -58,7 +58,6 @@ export class AuthService { if (typeof (response) === 'undefined') { return null; } - switch (provider) { case 'github': return normalisedUser = this.normaliseGithubUser(response); diff --git a/web/src/app/services/social-stats.service.ts b/web/src/app/services/social-stats.service.ts new file mode 100644 index 0000000..6fe89c6 --- /dev/null +++ b/web/src/app/services/social-stats.service.ts @@ -0,0 +1,32 @@ +import { Injectable } from '@angular/core'; +import { + AngularFirestore, + AngularFirestoreCollection, +} from 'angularfire2/firestore'; +import { SocialStatsHistory } from '../models/socialStatsHistory'; +import { Observable, from } from 'rxjs'; +import { catchError, map } from 'rxjs/operators'; +import { ErrorService } from './error.service'; + +@Injectable({ + providedIn: 'root' +}) +export class SocialStatsService { + + public socialStatsHistory: AngularFirestoreCollection; + + constructor( + private db: AngularFirestore, + private errorService: ErrorService, + ) { + this.socialStatsHistory = this.db.collection('socialStatsHistory'); + } + + createSocialStats(socialStat: SocialStatsHistory): Observable { + return from(this.socialStatsHistory.add(socialStat)) + .pipe( + map(res => res), + catchError(error => this.errorService.logError(error)) + ); + } +} diff --git a/web/src/app/services/user.service.ts b/web/src/app/services/user.service.ts index 9cfd6c7..ded4180 100644 --- a/web/src/app/services/user.service.ts +++ b/web/src/app/services/user.service.ts @@ -4,7 +4,7 @@ import { map, catchError } from 'rxjs/operators'; import { AngularFirestore, AngularFirestoreCollection, - AngularFirestoreDocument + QuerySnapshot, } from 'angularfire2/firestore'; import { ErrorService } from './error.service'; import { AuthService } from './auth.service'; @@ -40,7 +40,7 @@ export class UserService { } getUserSocialDetails(providerId: string, uid: string): Observable { - return from(this.userSocial.ref.where(`${providerId}.reference`, '==', uid).get()) + return from(this.userSocial.ref.where(`${providerId}.userId`, '==', uid).get()) .pipe( map(response => this.getSocialDataFromPayload(response)), catchError(error => this.errorService.logError(error)) @@ -57,11 +57,31 @@ export class UserService { } addRefID(user): UserSocial { - const normalisedResponse = { ...user.additionalUserInfo.profile, reference: user.uid }; + const normalisedResponse = { ...user.additionalUserInfo.profile, userId: user.uid }; return normalisedResponse; } - saveUserSocial(social): Observable { + checkForSocialDoc(provider: string, userId: string): Observable { + return from(this.userSocial.ref.where(`${provider}.userId`, '==', userId).get()) + .pipe( + map((response: QuerySnapshot) => { + if (response.empty) { + return { empty: response.empty }; + } + return { empty: response.empty, id: response.docs.pop().id }; + }) + ); + } + + updateSocialDoc(id: string, social: UserSocial): Observable { + return from(this.userSocial.doc(id).set(social)) + .pipe( + map(response => this.formatUserSocial(response)), + catchError(err => this.errorService.logError(err)) + ); + } + + addSocialDoc(social: UserSocial): Observable { return from(this.userSocial.add(social)) .pipe( map(response => this.formatUserSocial(response)),