184 lines
3.4 KiB
TypeScript
184 lines
3.4 KiB
TypeScript
import { Category } from './category.model';
|
|
import { Question } from './question.model';
|
|
|
|
export interface QuizSessionHistory {
|
|
|
|
"time": {
|
|
"spent": number,
|
|
"limit": number | null,
|
|
"percentage": number
|
|
},
|
|
"createdAt": "2025-12-19T18:49:58.000Z"
|
|
id: string;
|
|
|
|
category?: {
|
|
id: string;
|
|
name: string;
|
|
slug: string;
|
|
icon: string;
|
|
color: string;
|
|
};
|
|
quizType: QuizType;
|
|
difficulty: string;
|
|
questions: {
|
|
answered: number,
|
|
total: number,
|
|
correct: number,
|
|
accuracy: number
|
|
};
|
|
score: {
|
|
earned: number
|
|
total: number
|
|
percentage: number
|
|
};
|
|
|
|
status: QuizStatus;
|
|
startedAt: string;
|
|
completedAt?: string;
|
|
isPassed?: boolean;
|
|
}
|
|
/**
|
|
* 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 {
|
|
success: true;
|
|
data: {
|
|
categoryId: string;
|
|
questionCount: number;
|
|
difficulty?: string; // 'easy', 'medium', 'hard', 'mixed'
|
|
quizType?: QuizType;
|
|
};
|
|
}
|
|
export interface QuizStartFormRequest {
|
|
|
|
categoryId: string;
|
|
questionCount: number;
|
|
difficulty?: string; // 'easy', 'medium', 'hard', 'mixed'
|
|
quizType?: QuizType;
|
|
}
|
|
|
|
/**
|
|
* Quiz Start Response
|
|
*/
|
|
export interface QuizStartResponse {
|
|
success: boolean;
|
|
data: {
|
|
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[];
|
|
}
|