add changes

This commit is contained in:
AD2025
2025-11-13 23:15:11 +02:00
parent 9746cfbc79
commit 41565aec12
88 changed files with 18629 additions and 1 deletions

View File

@@ -0,0 +1,76 @@
/**
* Category Interface
* Represents a quiz category
*/
export interface Category {
id: string;
name: string;
slug: string;
description: string;
icon?: string;
color?: string;
questionCount: number;
displayOrder?: number;
isActive: boolean;
guestAccessible: boolean;
createdAt: string;
updatedAt: string;
}
/**
* Category Detail with Stats
*/
export interface CategoryDetail extends Category {
questionPreview?: QuestionPreview[];
stats?: CategoryStats;
}
/**
* Category Statistics
*/
export interface CategoryStats {
totalQuestions: number;
questionsByDifficulty: {
easy: number;
medium: number;
hard: number;
};
totalAttempts: number;
totalCorrect: number;
averageAccuracy: number;
}
/**
* Question Preview (limited info)
*/
export interface QuestionPreview {
id: string;
questionText: string;
questionType: QuestionType;
difficulty: Difficulty;
points: number;
accuracy?: number;
}
/**
* Question Types
*/
export type QuestionType = 'multiple_choice' | 'true_false' | 'written';
/**
* Difficulty Levels
*/
export type Difficulty = 'easy' | 'medium' | 'hard';
/**
* Category Create/Update Request
*/
export interface CategoryFormData {
name: string;
slug?: string;
description: string;
icon?: string;
color?: string;
displayOrder?: number;
guestAccessible: boolean;
}

View File

@@ -0,0 +1,148 @@
import { User } from './user.model';
import { QuizSession } from './quiz.model';
/**
* User Dashboard Response
*/
export interface UserDashboard {
success: boolean;
totalQuizzes: number;
totalQuestionsAnswered: number;
overallAccuracy: number;
currentStreak: number;
longestStreak: number;
averageScore: number;
recentQuizzes: QuizSession[];
categoryPerformance: CategoryPerformance[];
achievements?: Achievement[];
}
/**
* Category Performance
*/
export interface CategoryPerformance {
categoryId: string;
categoryName: string;
quizzesTaken: number;
averageScore: number;
accuracy: number;
}
/**
* User Quiz History
*/
export interface QuizHistoryResponse {
success: boolean;
sessions: QuizSession[];
pagination: PaginationInfo;
}
/**
* Pagination Info
*/
export interface PaginationInfo {
currentPage: number;
totalPages: number;
totalItems: number;
itemsPerPage: number;
}
/**
* Achievement
*/
export interface Achievement {
id: string;
name: string;
description: string;
icon: string;
earnedAt?: string;
progress?: number;
maxProgress?: number;
}
/**
* User Profile Update Request
*/
export interface UserProfileUpdate {
username?: string;
email?: string;
currentPassword?: string;
newPassword?: string;
}
/**
* Bookmark
*/
export interface Bookmark {
id: string;
userId: string;
questionId: string;
question?: any; // Will use Question type
createdAt: string;
}
/**
* Bookmarks Response
*/
export interface BookmarksResponse {
success: boolean;
bookmarks: any[]; // Will contain Question objects
}
/**
* Admin Statistics
*/
export interface AdminStatistics {
totalUsers: number;
activeUsers: number;
totalQuizSessions: number;
totalQuestions: number;
totalCategories: number;
mostPopularCategories: PopularCategory[];
averageQuizScore: number;
userGrowth: UserGrowthData[];
}
/**
* Popular Category
*/
export interface PopularCategory {
categoryId: string;
categoryName: string;
quizzesTaken: number;
}
/**
* User Growth Data
*/
export interface UserGrowthData {
date: string;
count: number;
}
/**
* Admin Users List Response
*/
export interface AdminUsersResponse {
success: boolean;
users: User[];
pagination: PaginationInfo;
}
/**
* Admin User Details
*/
export interface AdminUserDetails extends User {
quizHistory?: QuizSession[];
activityTimeline?: ActivityEvent[];
}
/**
* Activity Event
*/
export interface ActivityEvent {
id: string;
type: 'quiz_completed' | 'achievement_earned' | 'profile_updated';
description: string;
timestamp: string;
}

View File

@@ -0,0 +1,104 @@
/**
* Guest Session Interface
* Represents a temporary guest user session
*/
export interface GuestSession {
guestId: string;
sessionToken: string;
deviceId?: string;
quizzesTaken: number;
maxQuizzes: number;
remainingQuizzes: number;
expiresAt: string;
isConverted: boolean;
convertedUserId?: string;
createdAt: string;
updatedAt: string;
}
/**
* Guest Session Start Response
*/
export interface GuestSessionStartResponse {
success: boolean;
sessionToken: string;
guestId: string;
expiresAt: string;
maxQuizzes: number;
message?: string;
}
/**
* Guest Quiz Limit Response
*/
export interface GuestQuizLimitResponse {
success: boolean;
remainingQuizzes: number;
maxQuizzes: number;
quizzesTaken: number;
expiresAt: string;
upgradePrompt?: string;
}
/**
* Guest to User Conversion Request
*/
export interface GuestConversionRequest {
guestSessionId: string;
username: string;
email: string;
password: string;
}
/**
* Guest Settings (Admin)
*/
export interface GuestSettings {
id: string;
guestAccessEnabled: boolean;
maxQuizzesPerDay: number;
maxQuestionsPerQuiz: number;
sessionExpiryHours: number;
upgradePromptMessage: string;
createdAt: string;
updatedAt: string;
}
/**
* Guest Analytics (Admin)
*/
export interface GuestAnalytics {
totalGuestSessions: number;
activeGuestSessions: number;
guestToUserConversionRate: number;
averageQuizzesPerGuest: number;
totalGuestQuizzes: number;
conversionFunnel?: {
totalSessions: number;
startedQuiz: number;
completedQuiz: number;
converted: number;
};
}
/**
* Guest Quiz Limit
* Tracks remaining quiz attempts for guest
*/
export interface GuestLimit {
maxQuizzes: number;
quizzesTaken: number;
quizzesRemaining: number;
expiresAt?: string;
}
/**
* Guest State (for signal management)
*/
export interface GuestState {
session: GuestSession | null;
isGuest: boolean;
isLoading: boolean;
error: string | null;
quizLimit: GuestLimit | null;
}

View File

@@ -0,0 +1,90 @@
/**
* API Response Wrapper
*/
export interface ApiResponse<T> {
success: boolean;
data?: T;
message?: string;
error?: string;
}
/**
* API Error Response
*/
export interface ApiError {
message: string;
error?: string;
statusCode?: number;
timestamp?: string;
}
/**
* HTTP Error
*/
export interface HttpError {
status: number;
statusText: string;
message: string;
error?: any;
}
/**
* Loading State
*/
export interface LoadingState {
isLoading: boolean;
message?: string;
}
/**
* Toast Notification
*/
export interface ToastNotification {
id?: string;
type: 'success' | 'error' | 'warning' | 'info';
message: string;
duration?: number;
action?: ToastAction;
}
/**
* Toast Action
*/
export interface ToastAction {
label: string;
callback: () => void;
}
/**
* Sort Options
*/
export interface SortOptions {
sortBy: string;
sortOrder: 'asc' | 'desc';
}
/**
* Filter Options
*/
export interface FilterOptions {
[key: string]: any;
}
/**
* Search Options
*/
export interface SearchOptions {
query: string;
filters?: FilterOptions;
sort?: SortOptions;
page?: number;
limit?: number;
}
// Export all models
export * from './user.model';
export * from './category.model';
export * from './question.model';
export * from './quiz.model';
export * from './guest.model';
export * from './dashboard.model';

View File

@@ -0,0 +1,71 @@
import { QuestionType, Difficulty } from './category.model';
/**
* Question Interface
* Represents a quiz question
*/
export interface Question {
id: string;
questionText: string;
questionType: QuestionType;
difficulty: Difficulty;
categoryId: string;
categoryName?: string;
options?: string[]; // For multiple choice
correctAnswer: string | string[];
explanation: string;
points: number;
timeLimit?: number; // in seconds
tags?: string[];
keywords?: string[];
isActive: boolean;
isPublic: boolean;
timesAttempted?: number;
timesCorrect?: number;
accuracy?: number;
createdBy?: string;
createdAt: string;
updatedAt: string;
}
/**
* Question Create/Update Request
*/
export interface QuestionFormData {
questionText: string;
questionType: QuestionType;
difficulty: Difficulty;
categoryId: string;
options?: string[];
correctAnswer: string | string[];
explanation: string;
points?: number;
timeLimit?: number;
tags?: string[];
keywords?: string[];
isPublic: boolean;
isGuestAccessible: boolean;
}
/**
* Question Search Filters
*/
export interface QuestionSearchFilters {
q?: string; // search query
category?: string;
difficulty?: Difficulty;
questionType?: QuestionType;
isPublic?: boolean;
page?: number;
limit?: number;
}
/**
* Question Search Response
*/
export interface QuestionSearchResponse {
results: Question[];
totalCount: number;
page: number;
limit: number;
}

View File

@@ -0,0 +1,134 @@
import { Question } from './question.model';
/**
* Quiz Session Interface
* Represents an active or completed quiz session
*/
export interface QuizSession {
id: string;
userId?: string;
guestSessionId?: string;
categoryId: string;
categoryName?: string;
quizType: QuizType;
difficulty: string;
totalQuestions: number;
currentQuestionIndex: number;
score: number;
correctAnswers: number;
incorrectAnswers: number;
skippedAnswers: number;
status: QuizStatus;
startedAt: string;
completedAt?: string;
timeSpent?: number; // in seconds
isPassed?: boolean;
passingScore?: number;
}
/**
* Quiz Types
*/
export type QuizType = 'practice' | 'timed' | 'exam';
/**
* Quiz Status
*/
export type QuizStatus = 'in_progress' | 'completed' | 'abandoned';
/**
* Quiz Start Request
*/
export interface QuizStartRequest {
categoryId: string;
questionCount: number;
difficulty?: string; // 'easy', 'medium', 'hard', 'mixed'
quizType?: QuizType;
}
/**
* Quiz Start Response
*/
export interface QuizStartResponse {
success: boolean;
sessionId: string;
questions: Question[];
totalQuestions: number;
message?: string;
}
/**
* Quiz Answer Submission
*/
export interface QuizAnswerSubmission {
questionId: string;
answer: string | string[];
quizSessionId: string;
timeSpent?: number;
}
/**
* Quiz Answer Response
*/
export interface QuizAnswerResponse {
success: boolean;
isCorrect: boolean;
correctAnswer: string | string[];
explanation: string;
points: number;
score: number;
message?: string;
}
/**
* Quiz Results
*/
export interface QuizResults {
success: boolean;
score: number;
totalQuestions: number;
correctAnswers: number;
incorrectAnswers: number;
skippedAnswers: number;
percentage: number;
timeSpent: number;
isPassed: boolean;
performanceMessage: string;
questions: QuizQuestionResult[];
}
/**
* Quiz Question Result
*/
export interface QuizQuestionResult {
questionId: string;
questionText: string;
questionType: string;
userAnswer: string | string[];
correctAnswer: string | string[];
isCorrect: boolean;
explanation: string;
points: number;
timeSpent?: number;
}
/**
* Quiz Session State (for signal management)
*/
export interface QuizSessionState {
session: QuizSession | null;
questions: Question[];
currentQuestionIndex: number;
answers: Map<string, QuizAnswerResponse>;
isLoading: boolean;
error: string | null;
}
/**
* Quiz Review Response
*/
export interface QuizReviewResponse {
success: boolean;
session: QuizSession;
questions: QuizQuestionResult[];
}

View File

@@ -0,0 +1,61 @@
/**
* User Interface
* Represents a registered user in the system
*/
export interface User {
id: string;
username: string;
email: string;
role: 'user' | 'admin';
isActive: boolean;
totalQuizzesTaken?: number;
totalQuestionsAnswered?: number;
totalCorrectAnswers?: number;
currentStreak?: number;
longestStreak?: number;
averageScore?: number;
createdAt: string;
updatedAt: string;
}
/**
* User Registration Request
*/
export interface UserRegistration {
username: string;
email: string;
password: string;
guestSessionId?: string;
}
/**
* User Login Request
*/
export interface UserLogin {
email: string;
password: string;
}
/**
* Auth Response
*/
export interface AuthResponse {
success: boolean;
token: string;
user: User;
message?: string;
migratedStats?: {
quizzesTaken: number;
score: number;
};
}
/**
* Auth State (for signal management)
*/
export interface AuthState {
user: User | null;
isAuthenticated: boolean;
isLoading: boolean;
error: string | null;
}