add changes

This commit is contained in:
AD2025
2025-12-20 00:14:28 +02:00
parent 665919c1e2
commit 079c10e843
6 changed files with 381 additions and 273 deletions

View File

@@ -3,12 +3,12 @@ import { Question } from './question.model';
export interface QuizSessionHistory { export interface QuizSessionHistory {
"time": { time: {
"spent": number, spent: number,
"limit": number | null, limit: number | null,
"percentage": number percentage: number
}, },
"createdAt": "2025-12-19T18:49:58.000Z" createdAt: string;
id: string; id: string;
category?: { category?: {
@@ -111,7 +111,7 @@ export interface QuizStartResponse {
*/ */
export interface QuizAnswerSubmission { export interface QuizAnswerSubmission {
questionId: string; questionId: string;
answer: string | string[]; userAnswer: string | string[];
quizSessionId: string; quizSessionId: string;
timeSpent?: number; timeSpent?: number;
} }
@@ -146,18 +146,122 @@ export interface QuizResults {
questions: QuizQuestionResult[]; questions: QuizQuestionResult[];
} }
// Response from /complete endpoint - questions are statistics
export interface CompletedQuizResult {
sessionId: string;
status: string;
category: {
id: string;
name: string;
slug: string;
icon: string;
color: string
},
quizType: string
difficulty: string
score: {
earned: number,
total: number,
percentage: number
},
questions: {
total: number,
answered: number,
correct: number,
incorrect: number,
unanswered: number
},
accuracy: number,
isPassed: boolean,
time: {
started: string,
completed: string,
taken: number,
limit: number,
isTimeout: boolean
}
}
export interface CompletedQuizResponse {
success: boolean
data: CompletedQuizResult
}
// Response from /review endpoint - questions are detailed array
export interface QuizReviewResult {
session: {
id: string;
status: string;
quizType: string;
difficulty: string;
category: {
id: string;
name: string;
slug: string;
icon: string;
color: string;
};
startedAt: string;
completedAt: string;
timeSpent: number;
};
summary: {
score: {
earned: number;
total: number;
percentage: number;
};
questions: {
total: number;
answered: number;
correct: number;
incorrect: number;
unanswered: number;
};
accuracy: number;
isPassed: boolean;
timeStatistics: {
totalTime: number;
averageTimePerQuestion: number;
timeLimit: number | null;
wasTimedOut: boolean;
};
};
questions: QuizQuestionResult[];
}
export interface QuizReviewResponse {
success: boolean;
data: QuizReviewResult;
message?: string;
}
/** /**
* Quiz Question Result * Quiz Question Result
*/ */
export interface QuizQuestionResult { export interface QuizQuestionResult {
questionId: string; id: string;
questionText: string; questionText: string;
questionType: string; questionType: string;
userAnswer: string | string[]; options: any;
correctAnswer: string | string[]; difficulty: string;
isCorrect: boolean;
explanation: string;
points: number; points: number;
explanation: string;
tags: string[];
order: number;
correctAnswer: string | string[];
userAnswer: string | string[] | null;
isCorrect: boolean | null;
resultStatus: 'correct' | 'incorrect' | 'unanswered';
pointsEarned: number;
pointsPossible: number;
timeTaken: number | null;
answeredAt: string | null;
showExplanation: boolean;
wasAnswered: boolean;
// Legacy support
questionId?: string;
timeSpent?: number; timeSpent?: number;
} }

View File

@@ -10,7 +10,11 @@ import {
QuizAnswerSubmission, QuizAnswerSubmission,
QuizAnswerResponse, QuizAnswerResponse,
QuizResults, QuizResults,
QuizStartFormRequest QuizStartFormRequest,
CompletedQuizResult,
CompletedQuizResponse,
QuizReviewResult,
QuizReviewResponse
} from '../models/quiz.model'; } from '../models/quiz.model';
import { ToastService } from './toast.service'; import { ToastService } from './toast.service';
import { StorageService } from './storage.service'; import { StorageService } from './storage.service';
@@ -37,7 +41,7 @@ export class QuizService {
readonly questions = this._questions.asReadonly(); readonly questions = this._questions.asReadonly();
// Quiz results state // Quiz results state
private readonly _quizResults = signal<QuizResults | null>(null); private readonly _quizResults = signal<CompletedQuizResult | QuizReviewResult | QuizResults | null>(null);
readonly quizResults = this._quizResults.asReadonly(); readonly quizResults = this._quizResults.asReadonly();
// Loading states // Loading states
@@ -131,7 +135,22 @@ export class QuizService {
submitAnswer(submission: QuizAnswerSubmission): Observable<QuizAnswerResponse> { submitAnswer(submission: QuizAnswerSubmission): Observable<QuizAnswerResponse> {
this._isSubmittingAnswer.set(true); this._isSubmittingAnswer.set(true);
return this.http.post<QuizAnswerResponse>(`${this.apiUrl}/submit`, submission).pipe( return this.http.post<any>(`${this.apiUrl}/submit`, submission).pipe(
map(response => {
// Backend returns: { success, data: { isCorrect, pointsEarned, feedback: { explanation, correctAnswer }, sessionProgress: { currentScore } } }
// Frontend expects: { success, isCorrect, correctAnswer, explanation, points, score }
const backendData = response.data;
const mappedResponse: QuizAnswerResponse = {
success: response.success,
isCorrect: backendData.isCorrect,
correctAnswer: backendData.feedback?.correctAnswer || '',
explanation: backendData.feedback?.explanation || '',
points: backendData.pointsEarned || 0,
score: backendData.sessionProgress?.currentScore || 0,
message: response.message
};
return mappedResponse;
}),
tap(response => { tap(response => {
if (response.success) { if (response.success) {
// Update session state // Update session state
@@ -163,13 +182,13 @@ export class QuizService {
/** /**
* Complete the quiz session * Complete the quiz session
*/ */
completeQuiz(sessionId: string): Observable<QuizResults> { completeQuiz(sessionId: string): Observable<CompletedQuizResponse> {
this._isCompletingQuiz.set(true); this._isCompletingQuiz.set(true);
return this.http.post<QuizResults>(`${this.apiUrl}/complete`, { sessionId }).pipe( return this.http.post<CompletedQuizResponse>(`${this.apiUrl}/complete`, { sessionId }).pipe(
tap(results => { tap(results => {
if (results.success) { if (results.success) {
this._quizResults.set(results); this._quizResults.set(results.data);
// Update session status // Update session status
const currentSession = this._activeSession(); const currentSession = this._activeSession();
@@ -220,11 +239,11 @@ export class QuizService {
/** /**
* Get quiz review data * Get quiz review data
*/ */
reviewQuiz(sessionId: string): Observable<QuizResults> { reviewQuiz(sessionId: string): Observable<QuizReviewResponse> {
return this.http.get<QuizResults>(`${this.apiUrl}/review/${sessionId}`).pipe( return this.http.get<QuizReviewResponse>(`${this.apiUrl}/review/${sessionId}`).pipe(
tap(results => { tap(results => {
if (results.success) { if (results.success) {
this._quizResults.set(results); this._quizResults.set(results.data);
} }
}), }),
catchError(error => { catchError(error => {

View File

@@ -102,10 +102,10 @@
</h3> </h3>
</div> </div>
@if (!answerResult()?.isCorrect) { @if (answerResult() && !answerResult()!.isCorrect) {
<div class="correct-answer"> <div class="correct-answer">
<strong>Correct Answer:</strong> <strong>Correct Answer:</strong>
<p>{{ answerResult()?.correctAnswer }}</p> <p>{{ answerResult()!.correctAnswer }}</p>
</div> </div>
} }
@@ -123,9 +123,6 @@
</div> </div>
} }
{{this.answerForm?.valid }}
{{ !this.answerSubmitted()}}
{{ !this.isSubmittingAnswer()}}
<!-- Action Buttons --> <!-- Action Buttons -->
<div class="action-buttons"> <div class="action-buttons">
@if (!answerSubmitted()) { @if (!answerSubmitted()) {

View File

@@ -269,7 +269,7 @@ export class QuizQuestionComponent implements OnInit, OnDestroy {
const submission: QuizAnswerSubmission = { const submission: QuizAnswerSubmission = {
questionId: question.id, questionId: question.id,
answer: answer, userAnswer: answer,
quizSessionId: this.sessionId quizSessionId: this.sessionId
}; };

View File

@@ -1,243 +1,208 @@
<div class="quiz-review-container"> <div class="quiz-review-container">
<!-- Loading State --> <!-- Loading State -->
@if (isLoading()) { @if (isLoading()) {
<div class="loading-container"> <div class="loading-container">
<mat-spinner diameter="50"></mat-spinner> <mat-spinner diameter="50"></mat-spinner>
<p>Loading review...</p> <p>Loading review...</p>
</div> </div>
} }
<!-- Review Content --> <!-- Review Content -->
@if (!isLoading() && results()) { @if (!isLoading() && results()) {
<div class="review-content"> <div class="review-content">
<!-- Header Section --> <!-- Header Section -->
<div class="review-header"> <div class="review-header">
<button mat-icon-button (click)="backToResults()" class="back-btn"> <button mat-icon-button (click)="backToResults()" class="back-btn">
<mat-icon>arrow_back</mat-icon> <mat-icon>arrow_back</mat-icon>
</button> </button>
<div class="header-content"> <div class="header-content">
<h1 class="review-title">Quiz Review</h1> <h1 class="review-title">Quiz Review</h1>
<p class="review-subtitle">Review your answers and learn from mistakes</p> <p class="review-subtitle">Review your answers and learn from mistakes</p>
</div>
</div>
<!-- Summary Cards -->
<div class="summary-cards">
<mat-card class="summary-card">
<mat-card-content>
<div class="card-icon total">
<mat-icon>quiz</mat-icon>
</div>
<div class="card-info">
<div class="card-value">{{ allQuestions().length }}</div>
<div class="card-label">Total Questions</div>
</div>
</mat-card-content>
</mat-card>
<mat-card class="summary-card correct">
<mat-card-content>
<div class="card-icon success">
<mat-icon>check_circle</mat-icon>
</div>
<div class="card-info">
<div class="card-value">{{ correctCount() }}</div>
<div class="card-label">Correct</div>
</div>
</mat-card-content>
</mat-card>
<mat-card class="summary-card incorrect">
<mat-card-content>
<div class="card-icon error">
<mat-icon>cancel</mat-icon>
</div>
<div class="card-info">
<div class="card-value">{{ incorrectCount() }}</div>
<div class="card-label">Incorrect</div>
</div>
</mat-card-content>
</mat-card>
<mat-card class="summary-card score">
<mat-card-content>
<div class="card-icon primary">
<mat-icon>emoji_events</mat-icon>
</div>
<div class="card-info">
<div class="card-value">{{ results()!.percentage }}%</div>
<div class="card-label">Score</div>
</div>
</mat-card-content>
</mat-card>
</div>
<!-- Filter Tabs -->
<div class="filter-tabs">
<button
mat-stroked-button
[class.active]="filterType() === 'all'"
(click)="setFilter('all')"
>
<mat-icon>list</mat-icon>
All Questions ({{ allQuestions().length }})
</button>
<button
mat-stroked-button
[class.active]="filterType() === 'correct'"
(click)="setFilter('correct')"
class="correct-tab"
>
<mat-icon>check_circle</mat-icon>
Correct ({{ correctCount() }})
</button>
<button
mat-stroked-button
[class.active]="filterType() === 'incorrect'"
(click)="setFilter('incorrect')"
class="incorrect-tab"
>
<mat-icon>cancel</mat-icon>
Incorrect ({{ incorrectCount() }})
</button>
</div>
<!-- Questions List -->
<div class="questions-list">
@for (question of paginatedQuestions(); track question.questionId; let i = $index) {
<mat-card class="question-card" [class.incorrect]="!question.isCorrect">
<mat-card-header>
<div class="question-header-content">
<div class="question-number-badge" [class.correct]="question.isCorrect">
<span class="number">{{ (pageIndex() * pageSize()) + i + 1 }}</span>
<mat-icon class="status-icon">
{{ question.isCorrect ? 'check_circle' : 'cancel' }}
</mat-icon>
</div>
<div class="question-meta">
<mat-chip class="type-chip">
{{ getQuestionTypeText(question.questionType) }}
</mat-chip>
<span class="points-badge">{{ question.points }} pts</span>
</div>
@if (isAuthenticated()) {
<button
mat-icon-button
class="bookmark-btn"
[class.bookmarked]="isBookmarked(question.questionId)"
(click)="toggleBookmark(question.questionId)"
[matTooltip]="isBookmarked(question.questionId) ? 'Remove bookmark' : 'Bookmark question'"
>
<mat-icon>
{{ isBookmarked(question.questionId) ? 'bookmark' : 'bookmark_border' }}
</mat-icon>
</button>
}
</div>
</mat-card-header>
<mat-card-content>
<div class="question-text">{{ question.questionText }}</div>
<mat-divider></mat-divider>
<div class="answer-section">
<div class="answer-row">
<div class="answer-label">Your Answer:</div>
<div class="answer-value" [class.incorrect]="!question.isCorrect">
{{ formatAnswer(question.userAnswer) || 'Not answered' }}
@if (!question.isCorrect) {
<mat-icon class="answer-icon error">close</mat-icon>
} @else {
<mat-icon class="answer-icon success">check</mat-icon>
}
</div>
</div>
@if (!question.isCorrect) {
<div class="answer-row correct-answer">
<div class="answer-label">Correct Answer:</div>
<div class="answer-value correct">
{{ formatAnswer(question.correctAnswer) }}
<mat-icon class="answer-icon success">check</mat-icon>
</div>
</div>
}
</div>
@if (question.explanation) {
<div class="explanation-section">
<div class="explanation-header">
<mat-icon>lightbulb</mat-icon>
<span>Explanation</span>
</div>
<p class="explanation-text">{{ question.explanation }}</p>
</div>
}
@if (question.timeSpent) {
<div class="time-spent">
<mat-icon>schedule</mat-icon>
<span>Time spent: {{ question.timeSpent }}s</span>
</div>
}
</mat-card-content>
</mat-card>
}
@if (paginatedQuestions().length === 0) {
<div class="empty-state">
<mat-icon>info</mat-icon>
<p>No questions match the selected filter</p>
</div>
}
</div>
<!-- Pagination -->
@if (totalQuestions() > pageSize()) {
<mat-paginator
[length]="totalQuestions()"
[pageSize]="pageSize()"
[pageIndex]="pageIndex()"
[pageSizeOptions]="[5, 10, 20, 50]"
(page)="onPageChange($event)"
showFirstLastButtons
>
</mat-paginator>
}
<!-- Action Buttons -->
<div class="action-buttons">
<button
mat-raised-button
(click)="backToResults()"
class="action-btn"
>
<mat-icon>arrow_back</mat-icon>
Back to Results
</button>
<button
mat-raised-button
color="primary"
(click)="retakeQuiz()"
class="action-btn"
>
<mat-icon>refresh</mat-icon>
Retake Quiz
</button>
<button
mat-raised-button
(click)="goToDashboard()"
class="action-btn"
>
<mat-icon>dashboard</mat-icon>
Dashboard
</button>
</div> </div>
</div> </div>
<!-- Summary Cards -->
<div class="summary-cards">
<mat-card class="summary-card">
<mat-card-content>
<div class="card-icon total">
<mat-icon>quiz</mat-icon>
</div>
<div class="card-info">
<div class="card-value">{{ allQuestions().length }}</div>
<div class="card-label">Total Questions</div>
</div>
</mat-card-content>
</mat-card>
<mat-card class="summary-card correct">
<mat-card-content>
<div class="card-icon success">
<mat-icon>check_circle</mat-icon>
</div>
<div class="card-info">
<div class="card-value">{{ correctCount() }}</div>
<div class="card-label">Correct</div>
</div>
</mat-card-content>
</mat-card>
<mat-card class="summary-card incorrect">
<mat-card-content>
<div class="card-icon error">
<mat-icon>cancel</mat-icon>
</div>
<div class="card-info">
<div class="card-value">{{ incorrectCount() }}</div>
<div class="card-label">Incorrect</div>
</div>
</mat-card-content>
</mat-card>
<mat-card class="summary-card score">
<mat-card-content>
<div class="card-icon primary">
<mat-icon>emoji_events</mat-icon>
</div>
<div class="card-info">
<div class="card-value">{{ scorePercentage() }}%</div>
<div class="card-label">Score</div>
</div>
</mat-card-content>
</mat-card>
</div>
<!-- Filter Tabs -->
<div class="filter-tabs">
<button mat-stroked-button [class.active]="filterType() === 'all'" (click)="setFilter('all')">
<mat-icon>list</mat-icon>
All Questions ({{ allQuestions().length }})
</button>
<button mat-stroked-button [class.active]="filterType() === 'correct'" (click)="setFilter('correct')"
class="correct-tab">
<mat-icon>check_circle</mat-icon>
Correct ({{ correctCount() }})
</button>
<button mat-stroked-button [class.active]="filterType() === 'incorrect'" (click)="setFilter('incorrect')"
class="incorrect-tab">
<mat-icon>cancel</mat-icon>
Incorrect ({{ incorrectCount() }})
</button>
</div>
<!-- Questions List -->
<div class="questions-list">
@for (question of paginatedQuestions(); track question.id; let i = $index) {
<mat-card class="question-card" [class.incorrect]="!question.isCorrect">
<mat-card-header>
<div class="question-header-content">
<div class="question-number-badge" [class.correct]="question.isCorrect">
<span class="number">{{ (pageIndex() * pageSize()) + i + 1 }}</span>
<mat-icon class="status-icon">
{{ question.isCorrect ? 'check_circle' : 'cancel' }}
</mat-icon>
</div>
<div class="question-meta">
<mat-chip class="type-chip">
{{ getQuestionTypeText(question.questionType) }}
</mat-chip>
<span class="points-badge">{{ question.points }} pts</span>
</div>
@if (isAuthenticated()) {
<button mat-icon-button class="bookmark-btn" [class.bookmarked]="isBookmarked(question.id)"
(click)="toggleBookmark(question.id)"
[matTooltip]="isBookmarked(question.id) ? 'Remove bookmark' : 'Bookmark question'">
<mat-icon>
{{ isBookmarked(question.id) ? 'bookmark' : 'bookmark_border' }}
</mat-icon>
</button>
}
</div>
</mat-card-header>
<mat-card-content>
<div class="question-text">{{ question.questionText }}</div>
<mat-divider></mat-divider>
<div class="answer-section">
<div class="answer-row">
<div class="answer-label">Your Answer:</div>
<div class="answer-value" [class.incorrect]="!question.isCorrect">
{{ formatAnswer(question.userAnswer ?? '') || 'Not answered' }}
@if (!question.isCorrect) {
<mat-icon class="answer-icon error">close</mat-icon>
} @else {
<mat-icon class="answer-icon success">check</mat-icon>
}
</div>
</div>
@if (!question.isCorrect) {
<div class="answer-row correct-answer">
<div class="answer-label">Correct Answer:</div>
<div class="answer-value correct">
{{ formatAnswer(question.correctAnswer) }}
<mat-icon class="answer-icon success">check</mat-icon>
</div>
</div>
}
</div>
@if (question.explanation) {
<div class="explanation-section">
<div class="explanation-header">
<mat-icon>lightbulb</mat-icon>
<span>Explanation</span>
</div>
<p class="explanation-text">{{ question.explanation }}</p>
</div>
}
@if (question.timeSpent) {
<div class="time-spent">
<mat-icon>schedule</mat-icon>
<span>Time spent: {{ question.timeSpent }}s</span>
</div>
}
</mat-card-content>
</mat-card>
}
@if (paginatedQuestions().length === 0) {
<div class="empty-state">
<mat-icon>info</mat-icon>
<p>No questions match the selected filter</p>
</div>
}
</div>
<!-- Pagination -->
@if (totalQuestions() > pageSize()) {
<mat-paginator [length]="totalQuestions()" [pageSize]="pageSize()" [pageIndex]="pageIndex()"
[pageSizeOptions]="[5, 10, 20, 50]" (page)="onPageChange($event)" showFirstLastButtons>
</mat-paginator>
}
<!-- Action Buttons -->
<div class="action-buttons">
<button mat-raised-button (click)="backToResults()" class="action-btn">
<mat-icon>arrow_back</mat-icon>
Back to Results
</button>
<button mat-raised-button color="primary" (click)="retakeQuiz()" class="action-btn">
<mat-icon>refresh</mat-icon>
Retake Quiz
</button>
<button mat-raised-button (click)="goToDashboard()" class="action-btn">
<mat-icon>dashboard</mat-icon>
Dashboard
</button>
</div>
</div>
} }
</div> </div>

View File

@@ -12,7 +12,7 @@ import { MatPaginatorModule, PageEvent } from '@angular/material/paginator';
import { Subject, takeUntil } from 'rxjs'; import { Subject, takeUntil } from 'rxjs';
import { QuizService } from '../../../core/services/quiz.service'; import { QuizService } from '../../../core/services/quiz.service';
import { StorageService } from '../../../core/services/storage.service'; import { StorageService } from '../../../core/services/storage.service';
import { QuizResults, QuizQuestionResult } from '../../../core/models/quiz.model'; import { QuizReviewResult, QuizQuestionResult } from '../../../core/models/quiz.model';
@Component({ @Component({
selector: 'app-quiz-review', selector: 'app-quiz-review',
@@ -41,25 +41,32 @@ export class QuizReviewComponent implements OnInit, OnDestroy {
readonly sessionId = signal<string>(''); readonly sessionId = signal<string>('');
readonly results = this.quizService.quizResults; readonly results = this.quizService.quizResults;
readonly isLoading = signal<boolean>(true); readonly isLoading = signal<boolean>(true);
// Pagination // Pagination
readonly pageSize = signal<number>(10); readonly pageSize = signal<number>(10);
readonly pageIndex = signal<number>(0); readonly pageIndex = signal<number>(0);
// Filter // Filter
readonly filterType = signal<'all' | 'correct' | 'incorrect'>('all'); readonly filterType = signal<'all' | 'correct' | 'incorrect'>('all');
// Computed values // Computed values - handle QuizReviewResult structure
readonly allQuestions = computed(() => this.results()?.questions ?? []); readonly allQuestions = computed(() => {
const res = this.results();
// Check if it's QuizReviewResult (has questions array)
if (res && 'questions' in res && Array.isArray(res.questions)) {
return res.questions;
}
return [];
});
readonly filteredQuestions = computed(() => { readonly filteredQuestions = computed(() => {
const questions = this.allQuestions(); const questions = this.allQuestions();
const filter = this.filterType(); const filter = this.filterType();
if (filter === 'all') return questions; if (filter === 'all') return questions;
if (filter === 'correct') return questions.filter(q => q.isCorrect); if (filter === 'correct') return questions.filter(q => q.isCorrect);
if (filter === 'incorrect') return questions.filter(q => !q.isCorrect); if (filter === 'incorrect') return questions.filter(q => !q.isCorrect);
return questions; return questions;
}); });
@@ -72,15 +79,31 @@ export class QuizReviewComponent implements OnInit, OnDestroy {
readonly totalQuestions = computed(() => this.filteredQuestions().length); readonly totalQuestions = computed(() => this.filteredQuestions().length);
readonly correctCount = computed(() => readonly correctCount = computed(() =>
this.allQuestions().filter(q => q.isCorrect).length this.allQuestions().filter(q => q.isCorrect).length
); );
readonly incorrectCount = computed(() => readonly incorrectCount = computed(() =>
this.allQuestions().filter(q => !q.isCorrect).length this.allQuestions().filter(q => !q.isCorrect).length
); );
readonly isAuthenticated = computed(() => readonly scorePercentage = computed(() => {
const res = this.results();
if (res && 'summary' in res) {
return res.summary.score.percentage;
}
return 0;
});
readonly sessionInfo = computed(() => {
const res = this.results();
if (res && 'session' in res) {
return res.session;
}
return null;
});
readonly isAuthenticated = computed(() =>
this.storageService.isAuthenticated() this.storageService.isAuthenticated()
); );
@@ -95,7 +118,7 @@ export class QuizReviewComponent implements OnInit, OnDestroy {
const id = params['sessionId']; const id = params['sessionId'];
if (id) { if (id) {
this.sessionId.set(id); this.sessionId.set(id);
// Check for filter query param // Check for filter query param
this.route.queryParams this.route.queryParams
.pipe(takeUntil(this.destroy$)) .pipe(takeUntil(this.destroy$))
@@ -174,7 +197,7 @@ export class QuizReviewComponent implements OnInit, OnDestroy {
const bookmarks = this.bookmarkedQuestions(); const bookmarks = this.bookmarkedQuestions();
const newBookmarks = new Set(bookmarks); const newBookmarks = new Set(bookmarks);
if (newBookmarks.has(questionId)) { if (newBookmarks.has(questionId)) {
newBookmarks.delete(questionId); newBookmarks.delete(questionId);
// TODO: Call bookmark service to remove bookmark // TODO: Call bookmark service to remove bookmark
@@ -184,7 +207,7 @@ export class QuizReviewComponent implements OnInit, OnDestroy {
// TODO: Call bookmark service to add bookmark // TODO: Call bookmark service to add bookmark
console.log('Add bookmark:', questionId); console.log('Add bookmark:', questionId);
} }
this.bookmarkedQuestions.set(newBookmarks); this.bookmarkedQuestions.set(newBookmarks);
} }