Skip to content
This repository has been archived by the owner on Oct 14, 2022. It is now read-only.

Commit

Permalink
Merge pull request #17 from futureleadersupc/refactor/auth-service-user
Browse files Browse the repository at this point in the history
refactor(auth): full rewrite of AuthService
  • Loading branch information
dalbitresb12 authored May 24, 2022
2 parents 087224b + ce98520 commit dd5e5b2
Show file tree
Hide file tree
Showing 18 changed files with 397 additions and 151 deletions.
2 changes: 1 addition & 1 deletion src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { NgModule } from "@angular/core";
import { RouterModule, Routes } from "@angular/router";
import { ProfileComponent } from "./profile/profile.component";
import { ProfileComponent } from "./core/pages/profile/profile.component";
import { SignInComponent } from "./auth/pages/signin/signin.component";
import { SignUpComponent } from "./auth/pages/signup/signup.component";
import { JobsComponent } from "./jobs/pages/jobs/jobs.component";
Expand Down
5 changes: 3 additions & 2 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { FormsModule } from "@angular/forms";

import { AppRoutingModule } from "./app-routing.module";
import { AppComponent } from "./app.component";
import { ProfileComponent } from "./profile/profile.component";
import { ProfileComponent } from "./core/pages/profile/profile.component";
import { SignInComponent } from "./auth/pages/signin/signin.component";
import { SignUpComponent } from "./auth/pages/signup/signup.component";
import { JobsComponent } from "./jobs/pages/jobs/jobs.component";
Expand All @@ -24,6 +24,7 @@ import { MatTooltipModule } from "@angular/material/tooltip";
import { MatSelectModule } from "@angular/material/select";

export const imports: NonNullable<NgModule["imports"]> = [
AppRoutingModule,
BrowserAnimationsModule,
HttpClientModule,
FormsModule,
Expand All @@ -48,7 +49,7 @@ export const imports: NonNullable<NgModule["imports"]> = [
SignUpComponent,
JobsComponent,
],
imports: [BrowserModule, AppRoutingModule, ...imports],
imports: [BrowserModule, ...imports],
providers: [],
bootstrap: [AppComponent],
})
Expand Down
39 changes: 39 additions & 0 deletions src/app/auth/hooks/use-user.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Subscription } from "rxjs";
import { Project, User } from "src/app/auth/model/user";
import { AuthService } from "src/app/auth/services/auth.service";
import { ProjectsService } from "src/app/auth/services/projects.service";
import { Nullable } from "src/app/common/utils/types";

export type UserSubscriptionHandler = (user: Nullable<User>) => void;

export class UseUser {
user: Nullable<User> = null;
projects: Project[] = [];
private userSubscription: Nullable<Subscription> = null;

constructor(
protected authService: AuthService,
protected projectsService: ProjectsService
) {}

protected handleUserInit(): void;
protected handleUserInit(handler: UserSubscriptionHandler): void;
protected handleUserInit(handler?: UserSubscriptionHandler) {
this.userSubscription = this.authService.user.subscribe(user => {
this.user = user;
if (user) {
this.projectsService.getByUser(user.id).subscribe(projects => {
this.projects = projects;
});
}
if (handler) handler(user);
});
}

protected handleUserDestroy() {
if (this.userSubscription) {
this.userSubscription.unsubscribe();
this.userSubscription = null;
}
}
}
17 changes: 17 additions & 0 deletions src/app/auth/model/user.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,26 @@
export interface UserImage {
href: string;
alt?: string;
}

export interface Project {
id: number;
title: string;
summary: string;
timestamp: number;
href?: string;
image?: UserImage;
}

export interface User {
id: number;
preferredName: string;
fullName: string;
email: string;
location: string;
profileViews: number;
biography: string;
about: string;
cover?: UserImage;
picture?: UserImage;
}
6 changes: 3 additions & 3 deletions src/app/auth/pages/signin/signin.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@
matInput
type="text"
placeholder="john.doe@gmail.com"
class="w-full" />
class="w-full"
[(ngModel)]="this.email" />
</mat-form-field>
<mat-form-field appearance="outline" class="w-full">
<mat-label>Password</mat-label>
<input matInput type="password" class="w-full" />
</mat-form-field>
<div class="my-2 w-full">
<button
routerLink="/"
type="submit"
(click)="this.handleLogin()"
class="w-full py-2 px-3 rounded-xl transition-colors text-white bg-slate-500 hover:bg-slate-700 font-semibold">
Sign In
</button>
Expand Down
34 changes: 32 additions & 2 deletions src/app/auth/pages/signin/signin.component.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,38 @@
import { Component } from "@angular/core";
import { Component, OnDestroy, OnInit } from "@angular/core";
import { Router } from "@angular/router";
import { UseUser } from "../../hooks/use-user";
import { AuthService } from "../../services/auth.service";
import { ProjectsService } from "../../services/projects.service";

@Component({
selector: "app-signin",
templateUrl: "./signin.component.html",
styleUrls: ["./signin.component.css"],
})
export class SignInComponent {}
export class SignInComponent extends UseUser implements OnInit, OnDestroy {
email = "";

constructor(
private router: Router,
authService: AuthService,
projectsService: ProjectsService
) {
super(authService, projectsService);
}

ngOnInit(): void {
this.handleUserInit(user => {
if (user) this.router.navigate(["/"]);
});
}

ngOnDestroy(): void {
this.handleUserDestroy();
}

handleLogin() {
if (this.email.length > 0) {
this.authService.login(this.email);
}
}
}
52 changes: 29 additions & 23 deletions src/app/auth/services/auth.service.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,41 @@
import { User } from "../model/user";
import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { BehaviorSubject } from "rxjs";
import { BaseService } from "src/app/common/services/base.service";
import { Nullable } from "src/app/common/utils/types";
import { User } from "../model/user";

@Injectable({
providedIn: "root",
})
export class AuthService {
static user: User = {
preferredName: "John",
fullName: "John Doe",
email: "john.doe@gmail.com",
location: "Lima, Peru",
profileViews: 367,
biography:
"Freelance UX/UI designer, 80+ projects in Web, Mobile (Android & iOS) and creative projects. Open to offers.",
about:
"I'm more experienced in e-commerce web projects and mobile banking apps, but also like to work with creative projects, such as landing pages or unusual corporate websites.",
};
static loggedIn = true;
export class AuthService extends BaseService<User> {
private _user = new BehaviorSubject<Nullable<User>>(null);

constructor(http: HttpClient) {
super("/users", http);
}

get user() {
return this._user;
}

static login(): void {
this.loggedIn = true;
get isLoggedIn() {
return this._user.value !== null;
}

static logout(): void {
this.loggedIn = false;
login(email: string) {
this.fetch<User[]>("get", `${this.endpoint}?email=${email}`).subscribe(
res => {
if (res.length !== 1) {
this._user.next(null);
return;
}
this._user.next(res[0]);
}
);
}

static getCurrentUser(): User | null {
if (this.loggedIn) {
return this.user;
}
return null;
logout() {
this._user.next(null);
}
}
19 changes: 19 additions & 0 deletions src/app/auth/services/projects.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { HttpClientModule } from "@angular/common/http";
import { TestBed } from "@angular/core/testing";

import { ProjectsService } from "./projects.service";

describe("ProjectsService", () => {
let service: ProjectsService;

beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientModule],
});
service = TestBed.inject(ProjectsService);
});

it("should be created", () => {
expect(service).toBeTruthy();
});
});
17 changes: 17 additions & 0 deletions src/app/auth/services/projects.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { BaseService } from "src/app/common/services/base.service";
import { Project } from "../model/user";

@Injectable({
providedIn: "root",
})
export class ProjectsService extends BaseService<Project> {
constructor(http: HttpClient) {
super("/projects", http);
}

getByUser(userId: number) {
return this.fetchAll(`${this.endpoint}?userId=${userId}`);
}
}
35 changes: 35 additions & 0 deletions src/app/common/services/base.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { TestBed } from "@angular/core/testing";
import { HttpClient, HttpClientModule } from "@angular/common/http";
import { Injectable } from "@angular/core";

import { BaseService } from "./base.service";

interface TestModel {
id: number;
name: string;
visible: boolean;
}

@Injectable({
providedIn: "root",
})
class TestService extends BaseService<TestModel> {
constructor(http: HttpClient) {
super("/test", http);
}
}

describe("BaseService", () => {
let service: BaseService<TestModel>;

beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientModule],
});
service = TestBed.inject(TestService);
});

it("should be created", () => {
expect(service).toBeTruthy();
});
});
Loading

0 comments on commit dd5e5b2

Please sign in to comment.