From 89116ffb2e4d3371ecff42ebd0bfad6ff37d4ebf Mon Sep 17 00:00:00 2001 From: Feiyang Zhu Date: Thu, 7 Dec 2023 23:02:28 -0500 Subject: [PATCH] add frontend error handling --- health_portal/src/app/app-routing.module.ts | 27 ++++++++-------- health_portal/src/app/app.component.css | 22 +++++++++++++ health_portal/src/app/app.component.html | 10 ++++-- health_portal/src/app/auth/auth.guard.spec.ts | 16 ++++++++++ health_portal/src/app/auth/auth.guard.ts | 28 ++++++++++++++++ .../create-consent.component.ts | 32 ++++++++----------- .../update-consent.component.ts | 27 +++++++++------- .../app/components/login/login.component.ts | 13 +++++--- .../create-profile.component.html | 10 +++--- .../create-profile.component.ts | 8 ++--- .../update-profile.component.html | 12 ++++--- .../update-profile.component.ts | 10 +++--- .../view-profile/view-profile.component.html | 8 ++--- .../app/components/signup/signup.component.ts | 9 ++++-- health_portal/src/app/service/auth.service.ts | 14 ++++++-- 15 files changed, 167 insertions(+), 79 deletions(-) create mode 100644 health_portal/src/app/auth/auth.guard.spec.ts create mode 100644 health_portal/src/app/auth/auth.guard.ts diff --git a/health_portal/src/app/app-routing.module.ts b/health_portal/src/app/app-routing.module.ts index 53ec36f..63f7ac3 100644 --- a/health_portal/src/app/app-routing.module.ts +++ b/health_portal/src/app/app-routing.module.ts @@ -19,24 +19,25 @@ import { UpdateConsentComponent } from "./components/consent/update-consent/upda import { ShowConsentComponent } from "./components/consent/show-consent/show-consent.component"; import { HealthAdviceComponent } from './components/analytics/health-advice/health-advice.component'; +import { AuthGuard } from "./auth/auth.guard"; const routes: Routes = [ { path: 'signup', component: SignupComponent }, { path: 'login', component: LoginComponent }, - { path: 'dashboard', component: DashboardComponent }, - { path: 'list-profiles', component: ListProfilesComponent }, - { path: 'create-profile', component: CreateProfileComponent }, - { path: 'view-profile/:profileId', component: ViewProfileComponent }, - { path: 'update-profile/:profileId', component: UpdateProfileComponent }, - { path: 'list-prescription/:profileId', component: ListPrescriptionComponent }, - { path: 'create-prescription/:profileId', component: CreatePrescriptionComponent }, - { path: 'view-prescription/:profileId/:prescriptionId', component: ViewPrescriptionComponent }, - { path: 'update-prescription/:profileId/:prescriptionId', component: UpdatePrescriptionComponent }, - { path: 'health-advice/:profileId', component: HealthAdviceComponent }, - { path: 'create-consent', component: CreateConsentComponent }, - { path: 'update-consent', component: UpdateConsentComponent }, - { path: 'show-consent', component: ShowConsentComponent } + { path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] }, + { path: 'list-profiles', component: ListProfilesComponent, canActivate: [AuthGuard] }, + { path: 'create-profile', component: CreateProfileComponent, canActivate: [AuthGuard] }, + { path: 'view-profile/:profileId', component: ViewProfileComponent, canActivate: [AuthGuard] }, + { path: 'update-profile/:profileId', component: UpdateProfileComponent, canActivate: [AuthGuard] }, + { path: 'list-prescription/:profileId', component: ListPrescriptionComponent, canActivate: [AuthGuard] }, + { path: 'create-prescription/:profileId', component: CreatePrescriptionComponent, canActivate: [AuthGuard] }, + { path: 'view-prescription/:profileId/:prescriptionId', component: ViewPrescriptionComponent, canActivate: [AuthGuard] }, + { path: 'update-prescription/:profileId/:prescriptionId', component: UpdatePrescriptionComponent, canActivate: [AuthGuard] }, + { path: 'health-advice/:profileId', component: HealthAdviceComponent, canActivate: [AuthGuard] }, + { path: 'create-consent', component: CreateConsentComponent, canActivate: [AuthGuard] }, + { path: 'update-consent', component: UpdateConsentComponent, canActivate: [AuthGuard] }, + { path: 'show-consent', component: ShowConsentComponent, canActivate: [AuthGuard] } ]; @NgModule({ diff --git a/health_portal/src/app/app.component.css b/health_portal/src/app/app.component.css index e69de29..68ee9c1 100644 --- a/health_portal/src/app/app.component.css +++ b/health_portal/src/app/app.component.css @@ -0,0 +1,22 @@ +.bar { + font-size: xx-large; + font-weight: bold; + color: #e4ffc3; + background-color: #02792a; + display: flex; + align-items: center; + justify-content: center; + height: 80px; +} + +button { + color: #e4ffc3; + background-color: #029835; + border: none; + padding: 15px 32px; + text-align: center; + font-size: 20px; + border-radius: 75%; + margin: 8px; + float: right; +} diff --git a/health_portal/src/app/app.component.html b/health_portal/src/app/app.component.html index e116da8..73615ba 100644 --- a/health_portal/src/app/app.component.html +++ b/health_portal/src/app/app.component.html @@ -1,6 +1,10 @@ -

Awesome Health: Your Personalized Health Portal

- - \ No newline at end of file +
+ Awesome Health: Your Personalized Health Portal +
+ +
+ + diff --git a/health_portal/src/app/auth/auth.guard.spec.ts b/health_portal/src/app/auth/auth.guard.spec.ts new file mode 100644 index 0000000..68889d2 --- /dev/null +++ b/health_portal/src/app/auth/auth.guard.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { AuthGuard } from './auth.guard'; + +describe('AuthGuard', () => { + let guard: AuthGuard; + + beforeEach(() => { + TestBed.configureTestingModule({}); + guard = TestBed.inject(AuthGuard); + }); + + it('should be created', () => { + expect(guard).toBeTruthy(); + }); +}); diff --git a/health_portal/src/app/auth/auth.guard.ts b/health_portal/src/app/auth/auth.guard.ts new file mode 100644 index 0000000..d7a3d11 --- /dev/null +++ b/health_portal/src/app/auth/auth.guard.ts @@ -0,0 +1,28 @@ +import { Injectable } from '@angular/core'; +import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot, UrlTree } from '@angular/router'; +import { Observable } from 'rxjs'; +import { AuthService } from "../service/auth.service"; + +@Injectable({ + providedIn: 'root' +}) +export class AuthGuard implements CanActivate { + + constructor( + private AuthService: AuthService, + private router: Router + ) { } + + canActivate( + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot): Observable | Promise | boolean | UrlTree { + // console.log(this.AuthService.getIdFromJwt()) + if (!this.AuthService.getIdFromJwt()){ + this.router.navigate(['/']) + return false; + } else { + return true; + } + } + +} diff --git a/health_portal/src/app/components/consent/create-consent/create-consent.component.ts b/health_portal/src/app/components/consent/create-consent/create-consent.component.ts index 9fcd8ea..6b2c764 100644 --- a/health_portal/src/app/components/consent/create-consent/create-consent.component.ts +++ b/health_portal/src/app/components/consent/create-consent/create-consent.component.ts @@ -11,7 +11,6 @@ import { Consent } from "../../../documents/consent"; }) export class CreateConsentComponent { - consent: Consent = new Consent(); permission: boolean; userId: string; profileId: string = "1"; @@ -29,23 +28,20 @@ export class CreateConsentComponent { } createConsent() { - this.consent.consentId = this.consentId; - this.consent.userId = this.userId; - this.consent.profileId = this.profileId; - this.consent.permission = this.permission; - this.consent.updatedAt = new Date(); - console.log('consent data', this.consent); - this.ConsentService.createConsent(this.consent) - .subscribe( - (response) => { - console.log('Consent created:', response); - }, - (error) => { - console.error('Error creating consent:', error); - } - ); - alert("Consent created successfully!"); - this.router.navigate(['/show-consent']) + const consentData = {}; + consentData["consentId"] = this.consentId; + consentData["userId"] = this.userId; + consentData["profileId"] = this.profileId; + consentData["permission"] = this.permission; + consentData["updatedAt"] = new Date(); + console.log('consent data', consentData); + if (this.permission === undefined){ + alert("Permission cannot be null."); + } else { + this.ConsentService.createConsent(consentData).subscribe((response) => {}); + alert("Consent created successfully!"); + this.router.navigate(['/show-consent']) + } } } diff --git a/health_portal/src/app/components/consent/update-consent/update-consent.component.ts b/health_portal/src/app/components/consent/update-consent/update-consent.component.ts index 44a1fb0..bf7ce49 100644 --- a/health_portal/src/app/components/consent/update-consent/update-consent.component.ts +++ b/health_portal/src/app/components/consent/update-consent/update-consent.component.ts @@ -44,19 +44,22 @@ export class UpdateConsentComponent { consentData["userId"] = this.userId; consentData["profileId"] = this.profileId; consentData["permission"] = this.permission; - console.log('consent id', this.consentId); console.log('consent data', consentData); - this.ConsentService.updateConsent(this.consentId, consentData) - .subscribe( - (response) => { - console.log('Consent updated:', response); - }, - (error) => { - console.error('Error updating consent:', error); - } - ); - alert("Consent updated successfully!"); - this.router.navigate(['/show-consent']) + if (this.permission === undefined) { + alert("Permission cannot be null."); + } else { + this.ConsentService.updateConsent(this.consentId, consentData) + .subscribe( + (response) => { + console.log('Consent updated:', response); + }, + (error) => { + console.error('Error updating consent:', error); + } + ); + alert("Consent updated successfully!"); + this.router.navigate(['/show-consent']) + } } deleteConsent() { diff --git a/health_portal/src/app/components/login/login.component.ts b/health_portal/src/app/components/login/login.component.ts index b8390cb..728ed67 100644 --- a/health_portal/src/app/components/login/login.component.ts +++ b/health_portal/src/app/components/login/login.component.ts @@ -29,14 +29,17 @@ export class LoginComponent { login() { this.service.login(this.loginForm.value).subscribe((response) => { - console.log(response); - if (response.token) { + console.log(response) alert("Welcome! You've been logged in :)"); const token = response.token; localStorage.setItem('JWT', token); this.router.navigateByUrl('/dashboard'); + }, + (error) => { + console.log(error) + alert("Errors occurred, please check if your password and email matches"); } - }) + ); } - -} \ No newline at end of file + +} diff --git a/health_portal/src/app/components/profiles/create-profile/create-profile.component.html b/health_portal/src/app/components/profiles/create-profile/create-profile.component.html index db39ae3..4d1bb12 100644 --- a/health_portal/src/app/components/profiles/create-profile/create-profile.component.html +++ b/health_portal/src/app/components/profiles/create-profile/create-profile.component.html @@ -19,7 +19,7 @@

Create Profile

- +
Required 3 Chars @@ -27,15 +27,15 @@

Create Profile

- +
Required
- +
- Required + Required
@@ -44,7 +44,7 @@

Create Profile

- +
diff --git a/health_portal/src/app/components/profiles/create-profile/create-profile.component.ts b/health_portal/src/app/components/profiles/create-profile/create-profile.component.ts index fc0ece3..6cb017f 100644 --- a/health_portal/src/app/components/profiles/create-profile/create-profile.component.ts +++ b/health_portal/src/app/components/profiles/create-profile/create-profile.component.ts @@ -23,7 +23,7 @@ export class CreateProfileComponent { private profileService: ProfileService, private router: Router, private fb: FormBuilder - ) { + ) { this.medicalHistoryForm = this.fb.group({ tableRows: this.fb.array([],[Validators.required]) }); @@ -38,7 +38,7 @@ export class CreateProfileComponent { return this.fb.group({ diseaseName: ['',[Validators.required]], diagnosedAt: ['',[Validators.required]], - treatment:[''], + treatment:['',[Validators.required]], }); } @@ -58,7 +58,7 @@ export class CreateProfileComponent { } save() { - this.profile.userId = this.userId; + this.profile.userId = this.userId; this.profile.medicalHistory = this.medicalHistoryForm.value.tableRows; console.log(this.medicalHistoryForm.value) this.profileService.createProfile(this.profile) @@ -80,7 +80,7 @@ export class CreateProfileComponent { onSubmit() { this.submitted = true; console.log(this.list); - this.save(); + this.save(); } gotoList() { diff --git a/health_portal/src/app/components/profiles/update-profile/update-profile.component.html b/health_portal/src/app/components/profiles/update-profile/update-profile.component.html index e16809c..ab69b5b 100644 --- a/health_portal/src/app/components/profiles/update-profile/update-profile.component.html +++ b/health_portal/src/app/components/profiles/update-profile/update-profile.component.html @@ -19,7 +19,7 @@

Update Profile

- +
Required 3 Chars @@ -27,15 +27,15 @@

Update Profile

- +
Required
- +
- Required + Required
@@ -44,7 +44,7 @@

Update Profile

- +
@@ -69,6 +69,8 @@

Update Profile

+
+
diff --git a/health_portal/src/app/components/profiles/update-profile/update-profile.component.ts b/health_portal/src/app/components/profiles/update-profile/update-profile.component.ts index e9fc3de..8b0c5c7 100644 --- a/health_portal/src/app/components/profiles/update-profile/update-profile.component.ts +++ b/health_portal/src/app/components/profiles/update-profile/update-profile.component.ts @@ -24,7 +24,7 @@ export class UpdateProfileComponent { private profileService: ProfileService, private router: Router, private fb: FormBuilder - ) { + ) { this.medicalHistoryForm = this.fb.group({ tableRows: this.fb.array([],[Validators.required]) }); @@ -50,7 +50,7 @@ export class UpdateProfileComponent { return this.fb.group({ diseaseName: [medicalHistory ? medicalHistory.diseaseName : '',[Validators.required]], diagnosedAt: [medicalHistory ? medicalHistory.diagnosedAt : '',[Validators.required]], - treatment:[medicalHistory ? medicalHistory.treatment : ''], + treatment:[medicalHistory ? medicalHistory.treatment : '',[Validators.required]], }); } @@ -70,7 +70,7 @@ export class UpdateProfileComponent { } save() { - this.profile.userId = this.userId; + this.profile.userId = this.userId; this.profile.medicalHistory = this.medicalHistoryForm.value.tableRows; console.log(this.medicalHistoryForm.value) this.profileService.createProfile(this.profile) @@ -92,11 +92,11 @@ export class UpdateProfileComponent { onSubmit() { this.submitted = true; console.log(this.list); - this.save(); + this.save(); } gotoList() { this.router.navigate(['/list-profiles']); } -} \ No newline at end of file +} diff --git a/health_portal/src/app/components/profiles/view-profile/view-profile.component.html b/health_portal/src/app/components/profiles/view-profile/view-profile.component.html index 5c57307..7e03fa8 100644 --- a/health_portal/src/app/components/profiles/view-profile/view-profile.component.html +++ b/health_portal/src/app/components/profiles/view-profile/view-profile.component.html @@ -1,4 +1,4 @@ -

Profile Details

+

Profile Details


@@ -6,7 +6,7 @@

Profile Details

{{profile.age}}
- {{profile.sex}} + {{profile.sex}}
{{profile.location}} @@ -16,13 +16,13 @@

Profile Details

{{profile.languagePreference}} -
+ - + diff --git a/health_portal/src/app/components/signup/signup.component.ts b/health_portal/src/app/components/signup/signup.component.ts index df81b02..78483c7 100644 --- a/health_portal/src/app/components/signup/signup.component.ts +++ b/health_portal/src/app/components/signup/signup.component.ts @@ -39,10 +39,13 @@ export class SignupComponent { } signup() { - alert(this.signupForm.value) + // alert(this.signupForm.value) this.service.signup(this.signupForm.value).subscribe((response) => { - alert("Nice to meet you! You've successfully created a new account."); - console.log(response); + console.log(response) + if (response) + alert("Nice to meet you! You've successfully created a new account."); + else + alert("Some issues occurred when creating your account, please double check."); }) } diff --git a/health_portal/src/app/service/auth.service.ts b/health_portal/src/app/service/auth.service.ts index 06288e3..c74cf91 100644 --- a/health_portal/src/app/service/auth.service.ts +++ b/health_portal/src/app/service/auth.service.ts @@ -1,8 +1,9 @@ import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; +import { jwtDecode } from "jwt-decode"; -// TODO change to deployed instance +// TODO change to deployed instance const BASE_URL = ['http://localhost:8080/'] @Injectable({ @@ -22,4 +23,13 @@ export class AuthService { return this.http.post(BASE_URL + "users/auth/login", loginRequest) } -} \ No newline at end of file + getIdFromJwt(): any { + const jwtToken = localStorage.getItem('JWT'); + try { + return jwtDecode(jwtToken)['sub']; + } catch(Error) { + return null; + } + } + +}
Medical HistoriesMedical History
Disease Name