diff --git a/frontend/package-lock.json b/frontend/package-lock.json index cd03979122..becb841779 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -21,7 +21,7 @@ "codemirror": "^6.0.1", "primeflex": "^3.3.1", "primeicons": "^7.0.0", - "primeng": "^17.18.10", + "primeng": "^17.18.11", "rxjs": "~7.8.0", "tslib": "^2.3.0", "typeface-poppins": "^1.1.13", diff --git a/frontend/package.json b/frontend/package.json index ddb5b5203d..5d310e53ca 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -25,7 +25,7 @@ "codemirror": "^6.0.1", "primeflex": "^3.3.1", "primeicons": "^7.0.0", - "primeng": "^17.18.10", + "primeng": "^17.18.11", "rxjs": "~7.8.0", "tslib": "^2.3.0", "typeface-poppins": "^1.1.13", diff --git a/frontend/src/_interceptors/error.interceptor.ts b/frontend/src/_interceptors/error.interceptor.ts index 8b72a7d96d..b8347f5c87 100644 --- a/frontend/src/_interceptors/error.interceptor.ts +++ b/frontend/src/_interceptors/error.interceptor.ts @@ -9,7 +9,6 @@ export class ErrorInterceptor implements HttpInterceptor { return next.handle(request).pipe( catchError(err => { console.error(err); - const errorMessage = err.error.message; return throwError(() => new Error(errorMessage, { cause: err })); }), diff --git a/frontend/src/_models/user.service.response.interface.ts b/frontend/src/_models/user.service.response.interface.ts new file mode 100644 index 0000000000..e7513160c4 --- /dev/null +++ b/frontend/src/_models/user.service.response.interface.ts @@ -0,0 +1,11 @@ +export interface UServRes { + message: string; + data: { + id: string; + username: string; + email: string; + accessToken: string; + isAdmin: boolean; + createdAt: string; + }; +} diff --git a/frontend/src/_services/authentication.service.ts b/frontend/src/_services/authentication.service.ts index aab6bdc66a..303303b39e 100644 --- a/frontend/src/_services/authentication.service.ts +++ b/frontend/src/_services/authentication.service.ts @@ -74,4 +74,29 @@ export class AuthenticationService extends ApiService { this.userSubject.next(null); this.router.navigate(['/account/login']); } + + // get user details from user service for authentication + getUserDetails() { + return this.http.get(`${this.apiUrl}/users/${this.userValue?.id}`, { observe: 'response' }).pipe( + map(response => { + if (response.status === 200) { + let user: User = {} as User; + if (response.body) { + const body: UServRes = response.body; + const data = body.data; + user = { + id: data.id, + username: data.username, + email: data.email, + accessToken: data.accessToken, + isAdmin: data.isAdmin, + createdAt: data.createdAt, + }; + } + return user; + } + return null; + }), + ); + } } diff --git a/frontend/src/app/navigation-bar/navigation-bar.component.html b/frontend/src/app/navigation-bar/navigation-bar.component.html index a19c0d1b38..c4ccb399d1 100644 --- a/frontend/src/app/navigation-bar/navigation-bar.component.html +++ b/frontend/src/app/navigation-bar/navigation-bar.component.html @@ -8,7 +8,11 @@ @if (user) { - + } @else {
- - - - -
- - -
-
- - -
-

Manage Questions

+ @if (loading) { + + + } @else { + +
+ @if (isAdmin) { + +
+ + +
+
+ } @else { +
+ } +
+ + +
+

Questions

+
+
+ + + @if (isAdmin) { + + Id + Title + Topics + Difficulty + + } @else { + Id + Title + Topics + Difficulty + } + + + + + @if (isAdmin) { + + {{ question.id }} + {{ question.title }} + {{ question.topics.join(', ') }} + {{ question.difficulty }} + + + + } @else { + {{ question.id }} + {{ question.title }} + {{ question.topics.join(', ') }} + {{ question.difficulty }} + } + + +
- - - - - Id - Title - Description - Topics - Difficulty - - - - - - - - - {{ question.id }} - {{ question.title }} - {{ question.description }} - {{ question.topics.join(', ') }} - {{ question.difficulty }} - - - - - - - +
+
+ } Manage Questions (successfulRequest)="onSuccessfulRequest($event)"> +
+
+

{{ clickedOnQuestion?.title }}

+ +
+
+

{{ clickedOnQuestion?.description }}

+
+
diff --git a/frontend/src/app/questions/questions.component.ts b/frontend/src/app/questions/questions.component.ts index d8ce7d2a80..7ab25bbe20 100644 --- a/frontend/src/app/questions/questions.component.ts +++ b/frontend/src/app/questions/questions.component.ts @@ -17,6 +17,8 @@ import { QuestionService } from '../../_services/question.service'; import { HttpErrorResponse } from '@angular/common/http'; import { QuestionDialogComponent } from './question-dialog.component'; import { Column } from './column.model'; +import { AuthenticationService } from '../../_services/authentication.service'; +import { User } from '../../_models/user.model'; @Component({ selector: 'app-questions', @@ -44,21 +46,20 @@ import { Column } from './column.model'; }) export class QuestionsComponent implements OnInit { loading = true; - questions: Question[] = []; - cols: Column[] = []; - question!: Question; - selectedQuestions!: Question[] | null; - isDialogVisible = false; + isAdmin = false; + isPanelVisible = false; + clickedOnQuestion: Question | null = null; constructor( private questionService: QuestionService, private messageService: MessageService, private confirmationService: ConfirmationService, + private AuthenticationService: AuthenticationService, ) {} ngOnInit() { @@ -67,6 +68,9 @@ export class QuestionsComponent implements OnInit { // fetch data from API call this.handleInitData(); + + // check if user is admin + this.checkIfAdmin(); } openNewQuestion() { @@ -77,6 +81,7 @@ export class QuestionsComponent implements OnInit { editQuestion(question: Question) { this.question = question; this.isDialogVisible = true; + this.isPanelVisible = false; } deleteSelectedQuestions() { @@ -129,6 +134,18 @@ export class QuestionsComponent implements OnInit { this.isDialogVisible = false; } + onRowSelect(question: Question) { + this.clickedOnQuestion = question; + if (!this.isDialogVisible) { + this.isPanelVisible = true; + } + } + + closePanel() { + this.isPanelVisible = false; + this.clickedOnQuestion = null; + } + onQuestionUpdate(question: Question) { this.questions[this.questions.findIndex(x => x.id == question.id)] = question; this.questions = [...this.questions]; @@ -155,4 +172,10 @@ export class QuestionsComponent implements OnInit { life: 3000, }); } + + checkIfAdmin() { + this.AuthenticationService.getUserDetails().subscribe((userData: User | null) => { + this.isAdmin = userData?.isAdmin ?? false; + }); + } }