diff --git a/angular.json b/angular.json index 4c0071b..e026cfb 100644 --- a/angular.json +++ b/angular.json @@ -83,7 +83,8 @@ "buildTarget": "carnet-portal-app:build:production" }, "development": { - "buildTarget": "carnet-portal-app:build:development" + "buildTarget": "carnet-portal-app:build:development", + "port": 5173 } }, "defaultConfiguration": "development" diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 64502c4..dc18765 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core'; import { RouterOutlet } from '@angular/router'; import { SecuredHeaderComponent } from './common/secured-header/secured-header.component'; -import { UserService } from './core/services/user.service'; +import { UserService } from './core/services/common/user.service'; import { FooterComponent } from './common/footer/footer.component'; import { CommonModule } from '@angular/common'; import { Subscription } from 'rxjs'; diff --git a/src/app/app.config.ts b/src/app/app.config.ts index 28d5c11..1c4d63a 100644 --- a/src/app/app.config.ts +++ b/src/app/app.config.ts @@ -3,12 +3,13 @@ import { provideRouter } from '@angular/router'; import { routes } from './app.routes'; import { provideClientHydration, withEventReplay } from '@angular/platform-browser'; -import { provideHttpClient } from '@angular/common/http'; +import { HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; import { provideCharts, withDefaultRegisterables, } from 'ng2-charts'; +import { AuthInterceptor } from './core/interceptors/auth.interceptor'; export const appConfig: ApplicationConfig = { @@ -17,5 +18,7 @@ export const appConfig: ApplicationConfig = { provideRouter(routes), provideClientHydration(withEventReplay()), provideHttpClient(), - provideCharts(withDefaultRegisterables())] + provideHttpClient(withInterceptorsFromDi()), + provideCharts(withDefaultRegisterables()), + { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },] }; diff --git a/src/app/auth/auth.guard.ts b/src/app/auth/auth.guard.ts index b05bba1..e1db278 100644 --- a/src/app/auth/auth.guard.ts +++ b/src/app/auth/auth.guard.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router'; -import { UserService } from '../core/services/user.service'; +import { UserService } from '../core/services/common/user.service'; @Injectable({ providedIn: 'root' diff --git a/src/app/common/secured-header/secured-header.component.ts b/src/app/common/secured-header/secured-header.component.ts index e6d36a5..04d23e7 100644 --- a/src/app/common/secured-header/secured-header.component.ts +++ b/src/app/common/secured-header/secured-header.component.ts @@ -1,8 +1,9 @@ import { Component, OnInit } from '@angular/core'; -import { UserService } from '../../core/services/user.service'; -import { Router } from '@angular/router'; +import { UserService } from '../../core/services/common/user.service'; import { AngularMaterialModule } from '../../shared/module/angular-material.module'; import { CommonModule } from '@angular/common'; +import { AuthService } from '../../core/services/common/auth.service'; +import { NavigationService } from '../../core/services/common/navigation.service'; @Component({ selector: 'app-secured-header', @@ -16,7 +17,8 @@ export class SecuredHeaderComponent implements OnInit { constructor( private userService: UserService, - private router: Router + private authService: AuthService, + private navigationService: NavigationService ) { } ngOnInit(): void { @@ -28,13 +30,12 @@ export class SecuredHeaderComponent implements OnInit { } logout(): void { - this.userService.clearUser(); - this.router.navigate(['/login']); + this.authService.logout(); this.showProfileMenu = false; } navigateTo(route: string): void { - this.router.navigate([route]); + this.navigationService.navigate([route]); this.showProfileMenu = false; } } \ No newline at end of file diff --git a/src/app/core/interceptors/auth.interceptor.ts b/src/app/core/interceptors/auth.interceptor.ts new file mode 100644 index 0000000..e2f6fac --- /dev/null +++ b/src/app/core/interceptors/auth.interceptor.ts @@ -0,0 +1,111 @@ +// auth.interceptor.ts +import { Injectable } from '@angular/core'; +import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HttpErrorResponse } from '@angular/common/http'; +import { Observable, throwError, BehaviorSubject } from 'rxjs'; +import { catchError, filter, switchMap, take } from 'rxjs/operators'; +import { AuthService } from '../services/common/auth.service'; + +@Injectable() +export class AuthInterceptor implements HttpInterceptor { + + private isRefreshing = false; + private refreshTokenSubject: BehaviorSubject = new BehaviorSubject(null); + + private requestQueue: { request: HttpRequest, next: HttpHandler }[] = []; + + constructor(private authService: AuthService) { } + + intercept(request: HttpRequest, next: HttpHandler): Observable> { + + // Add withCredentials to all requests + request = request.clone({ + withCredentials: true + }); + + return next.handle(request).pipe( + catchError((error: HttpErrorResponse) => { + if (error.status === 401) { + // Handle 401 Unauthorized responses + if (error.url?.includes('refresh-tokens')) { + return throwError(() => error); + } + + return this.handle401Error(request, next); + } else { + return throwError(() => error); + } + }) + ); + } + + private handle401Error(request: HttpRequest, next: HttpHandler): Observable> { + if (!this.isRefreshing) { + this.isRefreshing = true; + this.refreshTokenSubject.next(null); + + return this.authService.refreshToken().pipe( + switchMap((token: any) => { + this.isRefreshing = false; + this.refreshTokenSubject.next(token); + + // Retry all queued requests with new token + this.retryQueuedRequests(); + + // Retry the original request + request = request.clone({ + withCredentials: true + }); + + return next.handle(request); + }), + catchError((err) => { + this.isRefreshing = false; + this.authService.logout(); + return throwError(() => err); + + }) + ); + } else { + // If token refresh is already in progress, add to queue + return this.addRequestToQueue(request, next); + } + } + + private addRequestToQueue(request: HttpRequest, next: HttpHandler): Observable> { + return new Observable>(observer => { + const subscription = this.refreshTokenSubject.pipe( + filter(token => token !== null), + take(1) + ).subscribe(token => { + // Remove from queue + const index = this.requestQueue.findIndex(item => item.request === request); + if (index > -1) { + this.requestQueue.splice(index, 1); + } + + // Retry request with new token + next.handle(request).subscribe({ + next: event => observer.next(event), + error: err => observer.error(err), + complete: () => observer.complete() + }); + }); + + // Add to queue + this.requestQueue.push({ request, next }); + }); + } + + private retryQueuedRequests(): void { + // Process all queued requests + while (this.requestQueue.length > 0) { + let { request, next } = this.requestQueue.shift()!; + + request = request.clone({ + withCredentials: true + }); + + next.handle(request).subscribe(); + } + } +} \ No newline at end of file diff --git a/src/app/core/models/service-provider/basic-detail.ts b/src/app/core/models/service-provider/basic-detail.ts index 7364e8a..4664263 100644 --- a/src/app/core/models/service-provider/basic-detail.ts +++ b/src/app/core/models/service-provider/basic-detail.ts @@ -13,4 +13,5 @@ export interface BasicDetail { zip: string; issuingRegion: string; replacementRegion: string; + appid: string; } diff --git a/src/app/core/models/user.ts b/src/app/core/models/user.ts new file mode 100644 index 0000000..9fb2ab6 --- /dev/null +++ b/src/app/core/models/user.ts @@ -0,0 +1,18 @@ +export interface User { + roles?: string[] | null; + menus?: string[] | null; + menuDetails?: Menu[] | null; + userDetails?: UserDetail | null; +} + +export interface Menu { + name: string; + pageName: string +} + +export interface UserDetail { + spid: number; + urlKey: string; + logoName: string; + themeName: string; +} \ No newline at end of file diff --git a/src/app/core/services/auth.service.ts b/src/app/core/services/auth.service.ts deleted file mode 100644 index 1b96f6d..0000000 --- a/src/app/core/services/auth.service.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { HttpClient } from '@angular/common/http'; -import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs'; -import { environment } from '../../../environments/environment'; - -@Injectable({ - providedIn: 'root' -}) -export class AuthService { - private apiUrl = environment.apiUrl; - - constructor(private http: HttpClient) { } - - login(username: string, password: string): Observable { - return this.http.post(`${this.apiUrl}/login`, { p_emailaddr: username, p_password: password }); - } -} diff --git a/src/app/core/services/api-error-handler.service.ts b/src/app/core/services/common/api-error-handler.service.ts similarity index 100% rename from src/app/core/services/api-error-handler.service.ts rename to src/app/core/services/common/api-error-handler.service.ts diff --git a/src/app/core/services/common/auth.service.ts b/src/app/core/services/common/auth.service.ts new file mode 100644 index 0000000..8022334 --- /dev/null +++ b/src/app/core/services/common/auth.service.ts @@ -0,0 +1,49 @@ +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { Observable, tap } from 'rxjs'; +import { environment } from '../../../../environments/environment'; +import { UserService } from './user.service'; +import { StorageService } from './storage.service'; +import { Router } from '@angular/router'; +import { NotificationService } from './notification.service'; +import { ApiErrorHandlerService } from './api-error-handler.service'; + +@Injectable({ + providedIn: 'root' +}) +export class AuthService { + private apiUrl = environment.apiUrl; + + constructor(private http: HttpClient, + private userService: UserService, + private storageService: StorageService, + private router: Router, + private notificationService: NotificationService, + private errorHandler: ApiErrorHandlerService + ) { } + + login(username: string, password: string): Observable { + return this.http.post(`${this.apiUrl}/login`, { p_emailaddr: username, p_password: password }); + } + + refreshToken(): Observable { + return this.http.get(`${this.apiUrl}/refresh-tokens`, {}); + } + + logout(): void { + if (this.userService.isLoggedIn()) { + this.http.post(`${this.apiUrl}/logout`, {}).subscribe({ + next: (response) => { + this.userService.clearUser(); + this.storageService.clear(); + this.router.navigate(['/login']); + } + , error: (error) => { + let errorMessage = this.errorHandler.handleApiError(error, `Logout failed`); + this.notificationService.showError(errorMessage); + console.error('Logout failed:', error); + } + }); + } + } +} diff --git a/src/app/core/services/common.service.ts b/src/app/core/services/common/common.service.ts similarity index 88% rename from src/app/core/services/common.service.ts rename to src/app/core/services/common/common.service.ts index 33806ab..5fe778b 100644 --- a/src/app/core/services/common.service.ts +++ b/src/app/core/services/common/common.service.ts @@ -1,17 +1,17 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { catchError, map, Observable, of } from 'rxjs'; -import { Region } from '../models/region'; -import { Country } from '../models/country'; -import { State } from '../models/state'; -import { environment } from '../../../environments/environment'; -import { DeliveryType } from '../models/delivery-type'; -import { FeeType } from '../models/fee-type'; -import { TimeZone } from '../models/timezone'; -import { BondSurety } from '../models/bond-surety'; -import { CargoPolicy } from '../models/cargo-policy'; -import { CargoSurety } from '../models/cargo-surety'; -import { CarnetStatus } from '../models/carnet-status'; +import { Region } from '../../models/region'; +import { State } from '../../models/state'; +import { environment } from '../../../../environments/environment'; +import { DeliveryType } from '../../models/delivery-type'; +import { FeeType } from '../../models/fee-type'; +import { TimeZone } from '../../models/timezone'; +import { BondSurety } from '../../models/bond-surety'; +import { CargoPolicy } from '../../models/cargo-policy'; +import { CargoSurety } from '../../models/cargo-surety'; +import { CarnetStatus } from '../../models/carnet-status'; +import { Country } from '../../models/country'; @Injectable({ providedIn: 'root' diff --git a/src/app/core/services/cookie.service.ts b/src/app/core/services/common/cookie.service.ts similarity index 100% rename from src/app/core/services/cookie.service.ts rename to src/app/core/services/common/cookie.service.ts diff --git a/src/app/core/services/common/navigation.service.ts b/src/app/core/services/common/navigation.service.ts new file mode 100644 index 0000000..f55656b --- /dev/null +++ b/src/app/core/services/common/navigation.service.ts @@ -0,0 +1,50 @@ +import { Injectable } from '@angular/core'; +import { Router } from '@angular/router'; +import { Location } from '@angular/common'; +import { StorageService } from './storage.service'; + + +@Injectable({ + providedIn: 'root' +}) +export class NavigationService { + +// private readonly USER_APPID_KEY = 'CurrentAppId'; + + constructor(private router: Router, + private location: Location) { } + + /* Not applicable for this app + setCurrentAppId(appId: string): void { + this.storageService.setItem(this.USER_APPID_KEY, appId); + } + + getCurrentAppId(): string { + return this.storageService.getItem(this.USER_APPID_KEY) ?? ''; + } + + */ + + navigate(commands: any[], extras?: any): void { + //const currentAppId = this.getCurrentAppId(); + + // Prepend appId to all navigations + this.router.navigate(commands, extras); + } + + navigateByUrl(url: string, extras?: any): void { + // const currentAppId = this.getCurrentAppId(); + + // Ensure URL starts with current appId + const fullUrl = `/${url.startsWith('/') ? url : `/${url}`}`; + this.router.navigateByUrl(fullUrl, extras); + } + + goBack(): void { + this.location.back(); + } + + goForward(): void { + this.location.forward(); + } +} diff --git a/src/app/core/services/notification.service.ts b/src/app/core/services/common/notification.service.ts similarity index 100% rename from src/app/core/services/notification.service.ts rename to src/app/core/services/common/notification.service.ts diff --git a/src/app/core/services/storage.service.ts b/src/app/core/services/common/storage.service.ts similarity index 58% rename from src/app/core/services/storage.service.ts rename to src/app/core/services/common/storage.service.ts index 919d92e..611cbf6 100644 --- a/src/app/core/services/storage.service.ts +++ b/src/app/core/services/common/storage.service.ts @@ -21,6 +21,24 @@ export class StorageService { return null; } + get(key: string): T | null { + try { + const item = sessionStorage.getItem(key); + return item ? JSON.parse(item) as T : null; + } catch (e) { + console.error(`Error getting ${key} from session storage`, e); + return null; + } + } + + set(key: string, value: any): void { + try { + sessionStorage.setItem(key, JSON.stringify(value)); + } catch (e) { + console.error(`Error setting ${key} in session storage`, e); + } + } + removeItem(key: string): void { sessionStorage.removeItem(key); } diff --git a/src/app/core/services/timeformat.service.ts b/src/app/core/services/common/timeformat.service.ts similarity index 100% rename from src/app/core/services/timeformat.service.ts rename to src/app/core/services/common/timeformat.service.ts diff --git a/src/app/core/services/common/user.service.ts b/src/app/core/services/common/user.service.ts new file mode 100644 index 0000000..6670560 --- /dev/null +++ b/src/app/core/services/common/user.service.ts @@ -0,0 +1,131 @@ +import { Injectable, signal } from '@angular/core'; +import { StorageService } from './storage.service'; +import { BehaviorSubject, map, Observable, of, Subject, tap } from 'rxjs'; +import { environment } from '../../../../environments/environment'; +import { HttpClient } from '@angular/common/http'; +import { Menu, User, UserDetail } from '../../models/user'; + +@Injectable({ + providedIn: 'root' +}) +export class UserService { + private apiUrl = environment.apiUrl; + private apiDb = environment.apiDb; + + private spid: number = 0; + + userDetailsSignal = signal({}); + + private readonly USER_EMAIL_KEY = 'CurrentUserEmail'; + private readonly USER_DETAILS_KEY = 'CurrentUserData'; + + private userLoggedInSubject = new BehaviorSubject(false); + + constructor(private http: HttpClient, private storageService: StorageService) { } + + watchUser(): Observable { + return this.userLoggedInSubject.asObservable(); + } + + setUser(email: string): void { + if (!email) { + console.error('Cannot set empty user email'); + return; + } + + this.storageService.setItem(this.USER_EMAIL_KEY, email); + this.userLoggedInSubject.next(true); + } + + getUser(): string | null { + const user = this.storageService.getItem(this.USER_EMAIL_KEY); + if (!user) { + this.userLoggedInSubject.next(false); + } + return user; + } + + setUserDetails(): Observable { + const userDetails = this.getUserDetails(); + + if (userDetails) { + return of(userDetails); + } + + const email = this.getUser(); + + if (!email) { + console.error('invalid user'); + } + + return this.http.get(`${this.apiUrl}/${this.apiDb}/GetUserDetails/${email}`).pipe( + map(response => this.mapToUser(response)), + tap(user => this.saveUserToStorage(user))); + } + + getUserDetails(): User | null { + return this.storageService.get(this.USER_DETAILS_KEY); + } + + clearUser(): void { + this.storageService.removeItem(this.USER_EMAIL_KEY); + this.storageService.removeItem(this.USER_DETAILS_KEY); + this.userLoggedInSubject.next(false); + } + + isLoggedIn(): boolean { + return !!this.getUser(); + } + + getSafeUser(): string { + return this.getUser() || ''; + } + + getUserSpid(): number { + if (this.spid === 0) { + const userDetails = this.getUserDetails(); + if (userDetails && userDetails.userDetails && userDetails.userDetails.spid) { + this.spid = userDetails.userDetails.spid; + } + } + return this.spid; + } + + private mapToUser(data: any): User { + return { + roles: data.roleDetails || null, + menus: data.menuDetails || null, + menuDetails: this.mapMenuDetails(data.menuPageDetails), + userDetails: this.mapUserDetails(data.userDetails) + }; + } + + private mapMenuDetails(menuPageDetails: any[]): Menu[] | null { + if (!menuPageDetails) return null; + + return menuPageDetails.map(item => ({ + name: item.MENUNAME, + pageName: item.PAGENAME + })); + } + + private mapUserDetails(userDetails: any): UserDetail | null { + if (!userDetails) return null; + + return { + spid: userDetails.SPID, + urlKey: userDetails.ENCURLKEY, + logoName: userDetails.LOGONAME, + themeName: userDetails.THEMENAME + }; + } + + private saveUserToStorage(user: User): void { + try { + this.storageService.set(this.USER_DETAILS_KEY, user); + this.userDetailsSignal.set(user); + } catch (e) { + console.error('Error saving user details to session storage', e); + } + } +} diff --git a/src/app/core/services/home.service.ts b/src/app/core/services/home.service.ts index 5360123..9643a4b 100644 --- a/src/app/core/services/home.service.ts +++ b/src/app/core/services/home.service.ts @@ -1,8 +1,8 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { UserService } from './user.service'; import { map, Observable } from 'rxjs'; import { environment } from '../../../environments/environment'; +import { UserService } from './common/user.service'; @Injectable({ providedIn: 'root' diff --git a/src/app/core/services/basic-detail.service.ts b/src/app/core/services/service-provider/basic-detail.service.ts similarity index 90% rename from src/app/core/services/basic-detail.service.ts rename to src/app/core/services/service-provider/basic-detail.service.ts index 80d848a..8e94e35 100644 --- a/src/app/core/services/basic-detail.service.ts +++ b/src/app/core/services/service-provider/basic-detail.service.ts @@ -1,9 +1,9 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { UserService } from './user.service'; -import { BasicDetail } from '../models/service-provider/basic-detail'; +import { BasicDetail } from '../../models/service-provider/basic-detail'; import { filter, map, Observable } from 'rxjs'; -import { environment } from '../../../environments/environment'; +import { environment } from '../../../../environments/environment'; +import { UserService } from '../common/user.service'; @Injectable({ providedIn: 'root' @@ -35,7 +35,8 @@ export class BasicDetailService { zip: basicDetails.ZIP, cargoSurety: basicDetails.CARGOSURETY, cargoPolicyNo: basicDetails.CARGOPOLICYNO, - bondSurety: basicDetails.BONDSURETY + bondSurety: basicDetails.BONDSURETY, + appid: basicDetails.ENCURLKEY }; } diff --git a/src/app/core/services/basic-fee.service.ts b/src/app/core/services/service-provider/basic-fee.service.ts similarity index 89% rename from src/app/core/services/basic-fee.service.ts rename to src/app/core/services/service-provider/basic-fee.service.ts index a23038a..b48af96 100644 --- a/src/app/core/services/basic-fee.service.ts +++ b/src/app/core/services/service-provider/basic-fee.service.ts @@ -1,10 +1,10 @@ import { Injectable } from '@angular/core'; -import { environment } from '../../../environments/environment'; +import { environment } from '../../../../environments/environment'; import { HttpClient } from '@angular/common/http'; -import { UserService } from './user.service'; -import { BasicFee } from '../models/service-provider/basic-fee'; import { map, Observable } from 'rxjs'; -import { CommonService } from './common.service'; +import { UserService } from '../common/user.service'; +import { BasicFee } from '../../models/service-provider/basic-fee'; +import { CommonService } from '../common/common.service'; @Injectable({ providedIn: 'root' diff --git a/src/app/core/services/carnet-fee.service.ts b/src/app/core/services/service-provider/carnet-fee.service.ts similarity index 88% rename from src/app/core/services/carnet-fee.service.ts rename to src/app/core/services/service-provider/carnet-fee.service.ts index 6ff3f3b..84ef7b2 100644 --- a/src/app/core/services/carnet-fee.service.ts +++ b/src/app/core/services/service-provider/carnet-fee.service.ts @@ -1,10 +1,10 @@ import { Injectable } from '@angular/core'; -import { UserService } from './user.service'; import { HttpClient } from '@angular/common/http'; import { map, Observable } from 'rxjs'; -import { environment } from '../../../environments/environment'; -import { CarnetFee } from '../models/service-provider/carnet-fee'; -import { CommonService } from './common.service'; +import { environment } from '../../../../environments/environment'; +import { CarnetFee } from '../../models/service-provider/carnet-fee'; +import { CommonService } from '../common/common.service'; +import { UserService } from '../common/user.service'; @Injectable({ providedIn: 'root' diff --git a/src/app/core/services/carnet-sequence.service.ts b/src/app/core/services/service-provider/carnet-sequence.service.ts similarity index 86% rename from src/app/core/services/carnet-sequence.service.ts rename to src/app/core/services/service-provider/carnet-sequence.service.ts index f5e624b..645a340 100644 --- a/src/app/core/services/carnet-sequence.service.ts +++ b/src/app/core/services/service-provider/carnet-sequence.service.ts @@ -1,9 +1,9 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { environment } from '../../../environments/environment'; -import { UserService } from './user.service'; import { map, Observable } from 'rxjs'; -import { CarnetSequence } from '../models/service-provider/carnet-sequence'; +import { environment } from '../../../../environments/environment'; +import { CarnetSequence } from '../../models/service-provider/carnet-sequence'; +import { UserService } from '../common/user.service'; @Injectable({ providedIn: 'root' diff --git a/src/app/core/services/contact.service.ts b/src/app/core/services/service-provider/contact.service.ts similarity index 93% rename from src/app/core/services/contact.service.ts rename to src/app/core/services/service-provider/contact.service.ts index 785cc88..f9dbf76 100644 --- a/src/app/core/services/contact.service.ts +++ b/src/app/core/services/service-provider/contact.service.ts @@ -1,9 +1,9 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { UserService } from './user.service'; -import { Contact } from '../models/service-provider/contact'; import { map, Observable } from 'rxjs'; -import { environment } from '../../../environments/environment'; +import { environment } from '../../../../environments/environment'; +import { Contact } from '../../models/service-provider/contact'; +import { UserService } from '../common/user.service'; @Injectable({ providedIn: 'root' diff --git a/src/app/core/services/continuation-sheet-fee.service.ts b/src/app/core/services/service-provider/continuation-sheet-fee.service.ts similarity index 88% rename from src/app/core/services/continuation-sheet-fee.service.ts rename to src/app/core/services/service-provider/continuation-sheet-fee.service.ts index de206ca..3daa274 100644 --- a/src/app/core/services/continuation-sheet-fee.service.ts +++ b/src/app/core/services/service-provider/continuation-sheet-fee.service.ts @@ -1,10 +1,10 @@ import { Injectable } from '@angular/core'; -import { UserService } from './user.service'; -import { ContinuationSheetFee } from '../models/service-provider/continuation-sheet-fee'; import { map, Observable } from 'rxjs'; import { HttpClient } from '@angular/common/http'; -import { environment } from '../../../environments/environment'; -import { CommonService } from './common.service'; +import { environment } from '../../../../environments/environment'; +import { ContinuationSheetFee } from '../../models/service-provider/continuation-sheet-fee'; +import { CommonService } from '../common/common.service'; +import { UserService } from '../common/user.service'; @Injectable({ providedIn: 'root' diff --git a/src/app/core/services/counterfoil-fee.service.ts b/src/app/core/services/service-provider/counterfoil-fee.service.ts similarity index 89% rename from src/app/core/services/counterfoil-fee.service.ts rename to src/app/core/services/service-provider/counterfoil-fee.service.ts index 0d28839..9667f69 100644 --- a/src/app/core/services/counterfoil-fee.service.ts +++ b/src/app/core/services/service-provider/counterfoil-fee.service.ts @@ -1,10 +1,10 @@ import { Injectable } from '@angular/core'; -import { UserService } from './user.service'; import { HttpClient } from '@angular/common/http'; -import { CounterfoilFee } from '../models/service-provider/counterfoil-fee'; import { map, Observable } from 'rxjs'; -import { environment } from '../../../environments/environment'; -import { CommonService } from './common.service'; +import { environment } from '../../../../environments/environment'; +import { CounterfoilFee } from '../../models/service-provider/counterfoil-fee'; +import { CommonService } from '../common/common.service'; +import { UserService } from '../common/user.service'; @Injectable({ providedIn: 'root' diff --git a/src/app/core/services/expedited-fee.service.ts b/src/app/core/services/service-provider/expedited-fee.service.ts similarity index 89% rename from src/app/core/services/expedited-fee.service.ts rename to src/app/core/services/service-provider/expedited-fee.service.ts index 31da534..59ef3db 100644 --- a/src/app/core/services/expedited-fee.service.ts +++ b/src/app/core/services/service-provider/expedited-fee.service.ts @@ -1,10 +1,10 @@ import { Injectable } from '@angular/core'; -import { ExpeditedFee } from '../models/service-provider/expedited-fee'; import { map, Observable } from 'rxjs'; import { HttpClient } from '@angular/common/http'; -import { UserService } from './user.service'; -import { environment } from '../../../environments/environment'; -import { CommonService } from './common.service'; +import { environment } from '../../../../environments/environment'; +import { ExpeditedFee } from '../../models/service-provider/expedited-fee'; +import { CommonService } from '../common/common.service'; +import { UserService } from '../common/user.service'; @Injectable({ providedIn: 'root' diff --git a/src/app/core/services/security-deposit.service.ts b/src/app/core/services/service-provider/security-deposit.service.ts similarity index 89% rename from src/app/core/services/security-deposit.service.ts rename to src/app/core/services/service-provider/security-deposit.service.ts index b5ef98d..0c3b8aa 100644 --- a/src/app/core/services/security-deposit.service.ts +++ b/src/app/core/services/service-provider/security-deposit.service.ts @@ -1,10 +1,10 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { UserService } from './user.service'; -import { SecurityDeposit } from '../models/service-provider/security-deposit'; import { map, Observable } from 'rxjs'; -import { environment } from '../../../environments/environment'; -import { CommonService } from './common.service'; +import { environment } from '../../../../environments/environment'; +import { SecurityDeposit } from '../../models/service-provider/security-deposit'; +import { CommonService } from '../common/common.service'; +import { UserService } from '../common/user.service'; @Injectable({ providedIn: 'root' diff --git a/src/app/core/services/user-preference.service.ts b/src/app/core/services/user-preference.service.ts index 1103deb..90302d6 100644 --- a/src/app/core/services/user-preference.service.ts +++ b/src/app/core/services/user-preference.service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; -import { CookieHelperService } from './cookie.service'; import { DEFAULT_USER_PREFERENCES, UserPreferences } from '../models/user-preference'; +import { CookieHelperService } from './common/cookie.service'; @Injectable({ providedIn: 'root' diff --git a/src/app/core/services/user.service.ts b/src/app/core/services/user.service.ts deleted file mode 100644 index 18e9fdc..0000000 --- a/src/app/core/services/user.service.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Injectable } from '@angular/core'; -import { StorageService } from './storage.service'; -import { BehaviorSubject, Observable } from 'rxjs'; - -@Injectable({ - providedIn: 'root' -}) -export class UserService { - - private readonly USER_EMAIL_KEY = 'CurrentUserEmail'; - private userLoggedInSubject = new BehaviorSubject(true); - - constructor(private storageService: StorageService) { } - - watchUser(): Observable { - return this.userLoggedInSubject.asObservable(); - } - - setUser(email: string): void { - if (!email) { - console.error('Cannot set empty user email'); - return; - } - - this.storageService.setItem(this.USER_EMAIL_KEY, email); - this.userLoggedInSubject.next(true); - } - - getUser(): string | null { - const user = this.storageService.getItem(this.USER_EMAIL_KEY); - if (!user) { - this.userLoggedInSubject.next(false); - } - return user; - } - - clearUser(): void { - this.storageService.removeItem(this.USER_EMAIL_KEY); - this.userLoggedInSubject.next(false); - } - - isLoggedIn(): boolean { - return !!this.getUser(); - } - - getSafeUser(): string { - return this.getUser() || ''; - } -} diff --git a/src/app/home/chart/chart.component.ts b/src/app/home/chart/chart.component.ts index 86c3b00..99bbca3 100644 --- a/src/app/home/chart/chart.component.ts +++ b/src/app/home/chart/chart.component.ts @@ -5,6 +5,7 @@ import { BaseChartDirective } from 'ng2-charts'; import { AngularMaterialModule } from '../../shared/module/angular-material.module'; import { Router } from '@angular/router'; import { CarnetStatus } from '../../core/models/carnet-status'; +import { NavigationService } from '../../core/services/common/navigation.service'; @Component({ selector: 'app-chart', @@ -17,10 +18,10 @@ export class ChartComponent { @Input() carnetStatuses: CarnetStatus[] = []; @Output() carnetStatusData = new EventEmitter(); - constructor(private router: Router) { } + constructor(private navigationService: NavigationService) { } navigateToManageProvider(spid: number): void { - this.router.navigate(['/service-provider', spid]); + this.navigationService.navigate(['/service-provider', spid]); } public chartClicked(event: any, chartIndex: number): void { diff --git a/src/app/home/home.component.ts b/src/app/home/home.component.ts index b169dd6..3592a89 100644 --- a/src/app/home/home.component.ts +++ b/src/app/home/home.component.ts @@ -3,8 +3,6 @@ import { HomeService } from '../core/services/home.service'; import { AngularMaterialModule } from '../shared/module/angular-material.module'; import { ChartComponent } from './chart/chart.component'; import { RouterLink } from '@angular/router'; -import { NotificationService } from '../core/services/notification.service'; -import { ApiErrorHandlerService } from '../core/services/api-error-handler.service'; import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator'; import { MatSort } from '@angular/material/sort'; import { MatTableDataSource } from '@angular/material/table'; @@ -12,8 +10,10 @@ import { UserPreferences } from '../core/models/user-preference'; import { UserPreferencesService } from '../core/services/user-preference.service'; import { CommonModule } from '@angular/common'; import { CustomPaginator } from '../shared/custom-paginator'; -import { CommonService } from '../core/services/common.service'; import { CarnetStatus } from '../core/models/carnet-status'; +import { ApiErrorHandlerService } from '../core/services/common/api-error-handler.service'; +import { NotificationService } from '../core/services/common/notification.service'; +import { CommonService } from '../core/services/common/common.service'; @Component({ selector: 'app-home', diff --git a/src/app/login/login.component.ts b/src/app/login/login.component.ts index 52f0045..7b47e49 100644 --- a/src/app/login/login.component.ts +++ b/src/app/login/login.component.ts @@ -1,10 +1,11 @@ import { Component, OnInit } from '@angular/core'; import { FormBuilder, FormGroup, Validators, ReactiveFormsModule } from '@angular/forms'; -import { Router } from '@angular/router'; -import { AuthService } from '../core/services/auth.service'; +import { AuthService } from '../core/services/common/auth.service'; +import { NavigationService } from '../core/services/common/navigation.service'; import { CommonModule } from '@angular/common'; import { AngularMaterialModule } from '../shared/module/angular-material.module'; -import { UserService } from '../core/services/user.service'; +import { User } from '../core/models/user'; +import { UserService } from '../core/services/common/user.service'; @Component({ selector: 'app-login', @@ -21,7 +22,7 @@ export class LoginComponent { private fb: FormBuilder, private authService: AuthService, private userService: UserService, - private router: Router + private navigationService: NavigationService ) { this.loginForm = this.fb.group({ username: ['', Validators.required], @@ -31,7 +32,7 @@ export class LoginComponent { ngOnInit(): void { if (this.userService.isLoggedIn()) { - this.router.navigate(['/home']); + this.navigationService.navigate(['/home']); } } @@ -44,12 +45,11 @@ export class LoginComponent { this.authService.login(username, password).subscribe({ next: (response) => { - this.isLoading = false; - if (response?.msg) { - this.userService.setUser(username); - this.router.navigate(['/home']); + if (response?.message) { + this.userService.setUser(response?.email); + this.setUserData(); } else { - this.errorMessage = response?.error ?? response?.msg; + this.errorMessage = response?.error ?? response?.message; } }, error: (error) => { @@ -60,4 +60,24 @@ export class LoginComponent { }); } } + + + setUserData() { + + this.userService.setUserDetails().subscribe({ + next: (data: User) => { + if (data?.userDetails) { + this.navigationService.navigate(['home']); + } else { + this.errorMessage = "User doesn't have permissions."; + this.isLoading = false; + } + }, + error: (error: any) => { + this.isLoading = false; + this.errorMessage = "User doesn't have permissions."; + console.error('Error retrieving app data:', error); + } + }); + } } \ No newline at end of file diff --git a/src/app/service-provider/basic-details/basic-details.component.ts b/src/app/service-provider/basic-details/basic-details.component.ts index dde5bb6..64689b2 100644 --- a/src/app/service-provider/basic-details/basic-details.component.ts +++ b/src/app/service-provider/basic-details/basic-details.component.ts @@ -6,13 +6,13 @@ import { BasicDetail } from '../../core/models/service-provider/basic-detail'; import { Country } from '../../core/models/country'; import { Region } from '../../core/models/region'; import { State } from '../../core/models/state'; -import { CommonService } from '../../core/services/common.service'; +import { CommonService } from '../../core/services/common/common.service'; import { AngularMaterialModule } from '../../shared/module/angular-material.module'; import { CommonModule } from '@angular/common'; -import { NotificationService } from '../../core/services/notification.service'; +import { NotificationService } from '../../core/services/common/notification.service'; import { ZipCodeValidator } from '../../shared/validators/zipcode-validator'; -import { BasicDetailService } from '../../core/services/basic-detail.service'; -import { ApiErrorHandlerService } from '../../core/services/api-error-handler.service'; +import { BasicDetailService } from '../../core/services/service-provider/basic-detail.service'; +import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service'; import { BondSurety } from '../../core/models/bond-surety'; import { CargoSurety } from '../../core/models/cargo-surety'; import { CargoPolicy } from '../../core/models/cargo-policy'; diff --git a/src/app/service-provider/basic-fee/basic-fee.component.ts b/src/app/service-provider/basic-fee/basic-fee.component.ts index f418ad5..f3adbf3 100644 --- a/src/app/service-provider/basic-fee/basic-fee.component.ts +++ b/src/app/service-provider/basic-fee/basic-fee.component.ts @@ -1,6 +1,6 @@ import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core'; -import { BasicFeeService } from '../../core/services/basic-fee.service'; -import { NotificationService } from '../../core/services/notification.service'; +import { BasicFeeService } from '../../core/services/service-provider/basic-fee.service'; +import { NotificationService } from '../../core/services/common/notification.service'; import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator'; import { MatSort } from '@angular/material/sort'; import { MatTableDataSource } from '@angular/material/table'; @@ -9,10 +9,9 @@ import { AngularMaterialModule } from '../../shared/module/angular-material.modu import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; import { CommonModule } from '@angular/common'; import { MatDialog } from '@angular/material/dialog'; -import { ConfirmDialogComponent } from '../../shared/components/confirm-dialog/confirm-dialog.component'; import { CustomPaginator } from '../../shared/custom-paginator'; import { forkJoin } from 'rxjs'; -import { ApiErrorHandlerService } from '../../core/services/api-error-handler.service'; +import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service'; import { UserPreferences } from '../../core/models/user-preference'; @Component({ diff --git a/src/app/service-provider/carnet-fee/carnet-fee.component.ts b/src/app/service-provider/carnet-fee/carnet-fee.component.ts index e562565..fbce6fa 100644 --- a/src/app/service-provider/carnet-fee/carnet-fee.component.ts +++ b/src/app/service-provider/carnet-fee/carnet-fee.component.ts @@ -5,16 +5,15 @@ import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator'; import { MatSort } from '@angular/material/sort'; import { MatTableDataSource } from '@angular/material/table'; import { MatDialog } from '@angular/material/dialog'; -import { ConfirmDialogComponent } from '../../shared/components/confirm-dialog/confirm-dialog.component'; import { AngularMaterialModule } from '../../shared/module/angular-material.module'; -import { NotificationService } from '../../core/services/notification.service'; +import { NotificationService } from '../../core/services/common/notification.service'; import { CommonModule } from '@angular/common'; import { CustomPaginator } from '../../shared/custom-paginator'; -import { CommonService } from '../../core/services/common.service'; +import { CommonService } from '../../core/services/common/common.service'; import { CarnetFee } from '../../core/models/service-provider/carnet-fee'; import { FeeType } from '../../core/models/fee-type'; -import { CarnetFeeService } from '../../core/services/carnet-fee.service'; -import { ApiErrorHandlerService } from '../../core/services/api-error-handler.service'; +import { CarnetFeeService } from '../../core/services/service-provider/carnet-fee.service'; +import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service'; import { UserPreferences } from '../../core/models/user-preference'; @Component({ diff --git a/src/app/service-provider/carnet-sequence/carnet-sequence.component.ts b/src/app/service-provider/carnet-sequence/carnet-sequence.component.ts index b94248f..a2c9f80 100644 --- a/src/app/service-provider/carnet-sequence/carnet-sequence.component.ts +++ b/src/app/service-provider/carnet-sequence/carnet-sequence.component.ts @@ -2,8 +2,8 @@ import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angu import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; import { CarnetSequence } from '../../core/models/service-provider/carnet-sequence'; import { Subject, takeUntil } from 'rxjs'; -import { NotificationService } from '../../core/services/notification.service'; -import { CommonService } from '../../core/services/common.service'; +import { NotificationService } from '../../core/services/common/notification.service'; +import { CommonService } from '../../core/services/common/common.service'; import { Region } from '../../core/models/region'; import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator'; import { MatSort } from '@angular/material/sort'; @@ -13,8 +13,8 @@ import { CommonModule } from '@angular/common'; import { ConfirmDialogComponent } from '../../shared/components/confirm-dialog/confirm-dialog.component'; import { MatDialog } from '@angular/material/dialog'; import { CustomPaginator } from '../../shared/custom-paginator'; -import { CarnetSequenceService } from '../../core/services/carnet-sequence.service'; -import { ApiErrorHandlerService } from '../../core/services/api-error-handler.service'; +import { CarnetSequenceService } from '../../core/services/service-provider/carnet-sequence.service'; +import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service'; import { UserPreferences } from '../../core/models/user-preference'; @Component({ diff --git a/src/app/service-provider/contacts/contacts.component.ts b/src/app/service-provider/contacts/contacts.component.ts index f3c964f..98e660e 100644 --- a/src/app/service-provider/contacts/contacts.component.ts +++ b/src/app/service-provider/contacts/contacts.component.ts @@ -6,13 +6,13 @@ import { MatTableDataSource } from '@angular/material/table'; import { MatDialog } from '@angular/material/dialog'; import { ConfirmDialogComponent } from '../../shared/components/confirm-dialog/confirm-dialog.component'; import { AngularMaterialModule } from '../../shared/module/angular-material.module'; -import { NotificationService } from '../../core/services/notification.service'; +import { NotificationService } from '../../core/services/common/notification.service'; import { Contact } from '../../core/models/service-provider/contact'; import { PhonePipe } from '../../shared/pipes/phone.pipe'; import { CommonModule } from '@angular/common'; import { CustomPaginator } from '../../shared/custom-paginator'; -import { ContactService } from '../../core/services/contact.service'; -import { ApiErrorHandlerService } from '../../core/services/api-error-handler.service'; +import { ContactService } from '../../core/services/service-provider/contact.service'; +import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service'; import { UserPreferences } from '../../core/models/user-preference'; @Component({ diff --git a/src/app/service-provider/continuation-sheet-fee/continuation-sheet-fee.component.ts b/src/app/service-provider/continuation-sheet-fee/continuation-sheet-fee.component.ts index c876036..4071886 100644 --- a/src/app/service-provider/continuation-sheet-fee/continuation-sheet-fee.component.ts +++ b/src/app/service-provider/continuation-sheet-fee/continuation-sheet-fee.component.ts @@ -5,13 +5,13 @@ import { MatSort } from '@angular/material/sort'; import { MatTableDataSource } from '@angular/material/table'; import { MatDialog } from '@angular/material/dialog'; import { ConfirmDialogComponent } from '../../shared/components/confirm-dialog/confirm-dialog.component'; -import { NotificationService } from '../../core/services/notification.service'; +import { NotificationService } from '../../core/services/common/notification.service'; import { AngularMaterialModule } from '../../shared/module/angular-material.module'; import { CommonModule } from '@angular/common'; import { of } from 'rxjs'; import { CustomPaginator } from '../../shared/custom-paginator'; -import { ContinuationSheetFeeService } from '../../core/services/continuation-sheet-fee.service'; -import { ApiErrorHandlerService } from '../../core/services/api-error-handler.service'; +import { ContinuationSheetFeeService } from '../../core/services/service-provider/continuation-sheet-fee.service'; +import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service'; import { UserPreferences } from '../../core/models/user-preference'; @Component({ diff --git a/src/app/service-provider/counterfoil-fee/counterfoil-fee.component.ts b/src/app/service-provider/counterfoil-fee/counterfoil-fee.component.ts index 63f5b09..fe27464 100644 --- a/src/app/service-provider/counterfoil-fee/counterfoil-fee.component.ts +++ b/src/app/service-provider/counterfoil-fee/counterfoil-fee.component.ts @@ -5,13 +5,13 @@ import { MatSort } from '@angular/material/sort'; import { MatTableDataSource } from '@angular/material/table'; import { MatDialog } from '@angular/material/dialog'; import { ConfirmDialogComponent } from '../../shared/components/confirm-dialog/confirm-dialog.component'; -import { NotificationService } from '../../core/services/notification.service'; +import { NotificationService } from '../../core/services/common/notification.service'; import { AngularMaterialModule } from '../../shared/module/angular-material.module'; import { CommonModule } from '@angular/common'; import { CounterfoilFee } from '../../core/models/service-provider/counterfoil-fee'; import { CustomPaginator } from '../../shared/custom-paginator'; -import { CounterfoilFeeService } from '../../core/services/counterfoil-fee.service'; -import { ApiErrorHandlerService } from '../../core/services/api-error-handler.service'; +import { CounterfoilFeeService } from '../../core/services/service-provider/counterfoil-fee.service'; +import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service'; import { UserPreferences } from '../../core/models/user-preference'; @Component({ diff --git a/src/app/service-provider/expedited-fee/expedited-fee.component.ts b/src/app/service-provider/expedited-fee/expedited-fee.component.ts index 83a7e07..0eef821 100644 --- a/src/app/service-provider/expedited-fee/expedited-fee.component.ts +++ b/src/app/service-provider/expedited-fee/expedited-fee.component.ts @@ -6,17 +6,17 @@ import { MatTableDataSource } from '@angular/material/table'; import { MatDialog } from '@angular/material/dialog'; import { ConfirmDialogComponent } from '../../shared/components/confirm-dialog/confirm-dialog.component'; import { AngularMaterialModule } from '../../shared/module/angular-material.module'; -import { NotificationService } from '../../core/services/notification.service'; +import { NotificationService } from '../../core/services/common/notification.service'; import { CommonModule } from '@angular/common'; import { CustomPaginator } from '../../shared/custom-paginator'; import { ExpeditedFee } from '../../core/models/service-provider/expedited-fee'; import { DeliveryType } from '../../core/models/delivery-type'; import { TimeZone } from '../../core/models/timezone'; -import { CommonService } from '../../core/services/common.service'; +import { CommonService } from '../../core/services/common/common.service'; import { Subject, takeUntil } from 'rxjs'; -import { ExpeditedFeeService } from '../../core/services/expedited-fee.service'; -import { ApiErrorHandlerService } from '../../core/services/api-error-handler.service'; -import { TimeFormatService } from '../../core/services/timeformat.service'; +import { ExpeditedFeeService } from '../../core/services/service-provider/expedited-fee.service'; +import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service'; +import { TimeFormatService } from '../../core/services/common/timeformat.service'; import { UserPreferences } from '../../core/models/user-preference'; @Component({ diff --git a/src/app/service-provider/security-deposit/security-deposit.component.ts b/src/app/service-provider/security-deposit/security-deposit.component.ts index 4870bde..5da7257 100644 --- a/src/app/service-provider/security-deposit/security-deposit.component.ts +++ b/src/app/service-provider/security-deposit/security-deposit.component.ts @@ -6,14 +6,14 @@ import { MatTableDataSource } from '@angular/material/table'; import { MatDialog } from '@angular/material/dialog'; import { ConfirmDialogComponent } from '../../shared/components/confirm-dialog/confirm-dialog.component'; import { AngularMaterialModule } from '../../shared/module/angular-material.module'; -import { NotificationService } from '../../core/services/notification.service'; +import { NotificationService } from '../../core/services/common/notification.service'; import { CommonModule } from '@angular/common'; import { CustomPaginator } from '../../shared/custom-paginator'; import { Country } from '../../core/models/country'; -import { CommonService } from '../../core/services/common.service'; +import { CommonService } from '../../core/services/common/common.service'; import { SecurityDeposit } from '../../core/models/service-provider/security-deposit'; -import { SecurityDepositService } from '../../core/services/security-deposit.service'; -import { ApiErrorHandlerService } from '../../core/services/api-error-handler.service'; +import { SecurityDepositService } from '../../core/services/service-provider/security-deposit.service'; +import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service'; import { UserPreferences } from '../../core/models/user-preference'; @Component({ diff --git a/src/app/user-settings/user-settings.component.ts b/src/app/user-settings/user-settings.component.ts index 31030b8..4dfa455 100644 --- a/src/app/user-settings/user-settings.component.ts +++ b/src/app/user-settings/user-settings.component.ts @@ -3,7 +3,7 @@ import { UserPreferencesService } from '../core/services/user-preference.service import { UserPreferences } from '../core/models/user-preference'; import { AngularMaterialModule } from '../shared/module/angular-material.module'; import { CommonModule } from '@angular/common'; -import { NotificationService } from '../core/services/notification.service'; +import { NotificationService } from '../core/services/common/notification.service'; import { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms'; @Component({