add changes
This commit is contained in:
@@ -15,7 +15,7 @@ import { UserService } from '../../core/services/user.service';
|
||||
import { AuthService } from '../../core/services/auth.service';
|
||||
import { CategoryService } from '../../core/services/category.service';
|
||||
import { QuizHistoryResponse, PaginationInfo } from '../../core/models/dashboard.model';
|
||||
import { QuizSession } from '../../core/models/quiz.model';
|
||||
import { QuizSession, QuizSessionHistory } from '../../core/models/quiz.model';
|
||||
import { Category } from '../../core/models/category.model';
|
||||
|
||||
@Component({
|
||||
@@ -44,32 +44,32 @@ export class QuizHistoryComponent implements OnInit {
|
||||
private categoryService = inject(CategoryService);
|
||||
private router = inject(Router);
|
||||
private route = inject(ActivatedRoute);
|
||||
|
||||
|
||||
// Signals
|
||||
isLoading = signal<boolean>(true);
|
||||
history = signal<QuizSession[]>([]);
|
||||
history = signal<QuizSessionHistory[]>([]);
|
||||
pagination = signal<PaginationInfo | null>(null);
|
||||
categories = signal<Category[]>([]);
|
||||
error = signal<string | null>(null);
|
||||
|
||||
|
||||
// Filter and sort state
|
||||
currentPage = signal<number>(1);
|
||||
pageSize = signal<number>(10);
|
||||
selectedCategory = signal<string | null>(null);
|
||||
sortBy = signal<'date' | 'score'>('date');
|
||||
|
||||
|
||||
// Table columns
|
||||
displayedColumns: string[] = ['date', 'category', 'score', 'time', 'status', 'actions'];
|
||||
|
||||
|
||||
// Computed values
|
||||
isEmpty = computed(() => this.history().length === 0 && !this.isLoading());
|
||||
totalItems = computed(() => this.pagination()?.totalItems || 0);
|
||||
|
||||
|
||||
ngOnInit(): void {
|
||||
this.loadCategories();
|
||||
this.loadHistoryFromRoute();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load categories for filter
|
||||
*/
|
||||
@@ -83,7 +83,7 @@ export class QuizHistoryComponent implements OnInit {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load history based on route query params
|
||||
*/
|
||||
@@ -93,31 +93,31 @@ export class QuizHistoryComponent implements OnInit {
|
||||
const limit = params['limit'] ? parseInt(params['limit'], 10) : 10;
|
||||
const category = params['category'] || null;
|
||||
const sortBy = params['sortBy'] || 'date';
|
||||
|
||||
|
||||
this.currentPage.set(page);
|
||||
this.pageSize.set(limit);
|
||||
this.selectedCategory.set(category);
|
||||
this.sortBy.set(sortBy);
|
||||
|
||||
|
||||
this.loadHistory();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load quiz history
|
||||
*/
|
||||
loadHistory(): void {
|
||||
const state: any = (this.authService as any).authState();
|
||||
const user = state?.user;
|
||||
|
||||
|
||||
if (!user || !user.id) {
|
||||
this.router.navigate(['/login']);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
this.isLoading.set(true);
|
||||
this.error.set(null);
|
||||
|
||||
|
||||
(this.userService as any).getHistory(
|
||||
user.id,
|
||||
this.currentPage(),
|
||||
@@ -126,8 +126,8 @@ export class QuizHistoryComponent implements OnInit {
|
||||
this.sortBy()
|
||||
).subscribe({
|
||||
next: (response: QuizHistoryResponse) => {
|
||||
this.history.set(response.sessions || []);
|
||||
this.pagination.set(response.pagination);
|
||||
this.history.set(response.data.sessions || []);
|
||||
this.pagination.set(response.data.pagination);
|
||||
this.isLoading.set(false);
|
||||
},
|
||||
error: (err: any) => {
|
||||
@@ -137,7 +137,7 @@ export class QuizHistoryComponent implements OnInit {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle page change
|
||||
*/
|
||||
@@ -146,7 +146,7 @@ export class QuizHistoryComponent implements OnInit {
|
||||
this.pageSize.set(event.pageSize);
|
||||
this.updateUrlAndLoad();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle category filter change
|
||||
*/
|
||||
@@ -155,7 +155,7 @@ export class QuizHistoryComponent implements OnInit {
|
||||
this.currentPage.set(1); // Reset to first page
|
||||
this.updateUrlAndLoad();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle sort change
|
||||
*/
|
||||
@@ -164,7 +164,7 @@ export class QuizHistoryComponent implements OnInit {
|
||||
this.currentPage.set(1); // Reset to first page
|
||||
this.updateUrlAndLoad();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update URL with query params and reload data
|
||||
*/
|
||||
@@ -174,18 +174,18 @@ export class QuizHistoryComponent implements OnInit {
|
||||
limit: this.pageSize(),
|
||||
sortBy: this.sortBy()
|
||||
};
|
||||
|
||||
|
||||
if (this.selectedCategory()) {
|
||||
queryParams.category = this.selectedCategory();
|
||||
}
|
||||
|
||||
|
||||
this.router.navigate([], {
|
||||
relativeTo: this.route,
|
||||
queryParams,
|
||||
queryParamsHandling: 'merge'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* View quiz results
|
||||
*/
|
||||
@@ -194,7 +194,7 @@ export class QuizHistoryComponent implements OnInit {
|
||||
this.router.navigate(['/quiz', sessionId, 'results']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Review quiz
|
||||
*/
|
||||
@@ -203,13 +203,13 @@ export class QuizHistoryComponent implements OnInit {
|
||||
this.router.navigate(['/quiz', sessionId, 'review']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Format date
|
||||
*/
|
||||
formatDate(dateString: string | undefined): string {
|
||||
if (!dateString) return 'N/A';
|
||||
|
||||
|
||||
const date = new Date(dateString);
|
||||
return date.toLocaleDateString('en-US', {
|
||||
year: 'numeric',
|
||||
@@ -219,23 +219,23 @@ export class QuizHistoryComponent implements OnInit {
|
||||
minute: '2-digit'
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Format duration
|
||||
*/
|
||||
formatDuration(seconds: number | undefined): string {
|
||||
if (!seconds) return '0s';
|
||||
|
||||
|
||||
const minutes = Math.floor(seconds / 60);
|
||||
const secs = seconds % 60;
|
||||
|
||||
|
||||
if (minutes === 0) {
|
||||
return `${secs}s`;
|
||||
}
|
||||
|
||||
|
||||
return `${minutes}m ${secs}s`;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get score color
|
||||
*/
|
||||
@@ -245,7 +245,7 @@ export class QuizHistoryComponent implements OnInit {
|
||||
if (percentage >= 60) return 'warning';
|
||||
return 'error';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get status badge class
|
||||
*/
|
||||
@@ -261,7 +261,7 @@ export class QuizHistoryComponent implements OnInit {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Export to CSV
|
||||
*/
|
||||
@@ -269,32 +269,32 @@ export class QuizHistoryComponent implements OnInit {
|
||||
if (this.history().length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Create CSV header
|
||||
const headers = ['Date', 'Category', 'Score', 'Total Questions', 'Percentage', 'Time Spent', 'Status'];
|
||||
const csvRows = [headers.join(',')];
|
||||
|
||||
|
||||
// Add data rows
|
||||
this.history().forEach(session => {
|
||||
const percentage = ((session.score / session.totalQuestions) * 100).toFixed(2);
|
||||
const percentage = ((session.score.earned / session.questions.total) * 100).toFixed(2);
|
||||
const row = [
|
||||
this.formatDate(session.completedAt || session.startedAt),
|
||||
session.categoryName || 'Unknown',
|
||||
session.score.toString(),
|
||||
session.totalQuestions.toString(),
|
||||
session.category?.name || 'Unknown',
|
||||
session.score.earned.toString(),
|
||||
session.questions.total.toString(),
|
||||
`${percentage}%`,
|
||||
this.formatDuration(session.timeSpent),
|
||||
this.formatDuration(session.time.spent),
|
||||
session.status
|
||||
];
|
||||
csvRows.push(row.join(','));
|
||||
});
|
||||
|
||||
|
||||
// Create blob and download
|
||||
const csvContent = csvRows.join('\n');
|
||||
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
|
||||
const link = document.createElement('a');
|
||||
const url = URL.createObjectURL(blob);
|
||||
|
||||
|
||||
link.setAttribute('href', url);
|
||||
link.setAttribute('download', `quiz-history-${new Date().toISOString().split('T')[0]}.csv`);
|
||||
link.style.visibility = 'hidden';
|
||||
@@ -302,7 +302,7 @@ export class QuizHistoryComponent implements OnInit {
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Refresh history
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user