@schoolio/player
v1.2.2
Published
Quiz Player component for loading and playing quizzes, and attempts from Quiz Engine
Maintainers
Readme
@schoolio/player
React components for loading quizzes and displaying attempt results from Quiz Engine.
Components
- QuizPlayer - Interactive quiz-taking component
- AttemptViewer - Displays quiz attempt results with detailed breakdown
Installation
npm install @schoolio/playerUsage
import { QuizPlayer } from '@schoolio/player';
function MyQuizPage() {
return (
<QuizPlayer
quizId="QZ123"
lessonId="L12"
assignLessonId="assignLesson123"
courseId="course456"
childId="child789"
parentId="parent012"
apiBaseUrl="https://your-quiz-engine-url.com"
onComplete={(result) => {
console.log('Quiz completed!', result);
// result contains: attemptId, score, correctAnswers, totalQuestions, answers, timeSpentSeconds
}}
onError={(error) => {
console.error('Quiz error:', error);
}}
onProgress={(progress) => {
console.log(`Question ${progress.currentQuestion} of ${progress.totalQuestions}`);
}}
/>
);
}Props
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| quizId | string | Yes | The ID of the quiz to load |
| lessonId | string | Yes | Lesson ID from your app |
| assignLessonId | string | Yes | Assigned lesson ID for tracking |
| courseId | string | Yes | Course ID for tracking |
| childId | string | Yes | Student/child ID |
| parentId | string | Yes | Parent ID |
| apiBaseUrl | string | Yes | Base URL of your Quiz Engine API |
| authToken | string | No | Optional auth token for API requests |
| onComplete | function | No | Callback when quiz is completed |
| onError | function | No | Callback when an error occurs |
| onProgress | function | No | Callback on question navigation |
| className | string | No | CSS class for the container |
Quiz Result
When the quiz is completed, the onComplete callback receives:
interface QuizResult {
attemptId: string; // Unique attempt ID
score: number; // Percentage score (0-100)
correctAnswers: number; // Number of correct answers
totalQuestions: number; // Total questions in quiz
answers: QuizAnswerDetail[]; // Detailed answer data
timeSpentSeconds: number; // Time taken to complete
}Attempt Tracking
The component automatically:
- Creates a new attempt when started
- Saves progress as the student answers questions
- Resumes from where the student left off if they return
- Tracks attempt number (1st, 2nd, 3rd attempt, etc.)
- Records time spent on the quiz
API Endpoints
The component expects these endpoints on your Quiz Engine:
GET /api/external/quizzes/:id- Get quiz by IDPOST /api/external/quiz-attempts- Create new attemptPATCH /api/external/quiz-attempts/:id- Update attemptGET /api/external/quiz-attempts/:id- Get attempt by IDGET /api/external/quiz-attempts?assignLessonId=X&childId=Y- Get attempts
Customization
You can provide custom styling via the className prop and CSS:
.my-quiz-player {
/* Custom container styles */
}
.my-quiz-player .quiz-question {
/* Custom question styles */
}Using the API Client Directly
For more control, you can use the API client directly:
import { QuizApiClient } from '@schoolio/player';
const client = new QuizApiClient({
baseUrl: 'https://your-quiz-engine-url.com',
authToken: 'optional-auth-token',
});
// Fetch a quiz
const quiz = await client.getQuiz('quiz-id');
// Create an attempt
const attempt = await client.createAttempt({
quizId: 'quiz-id',
lessonId: 'lesson-id',
assignLessonId: 'assign-lesson-id',
courseId: 'course-id',
childId: 'child-id',
parentId: 'parent-id',
});
// Update attempt with answers
await client.updateAttempt(attempt.id, {
answers: [...],
status: 'completed',
score: 80,
correctAnswers: 8,
timeSpentSeconds: 300,
});AttemptViewer
The AttemptViewer component displays quiz attempt results with a summary and detailed question-by-question breakdown.
Usage
import { AttemptViewer } from '@schoolio/player';
function MyResultsPage() {
return (
<AttemptViewer
attemptId={123}
apiBaseUrl="https://your-quiz-engine-url.com"
/>
);
}Props
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| attemptId | number | Yes | The ID of the quiz attempt to display |
| apiBaseUrl | string | Yes | Base URL of your Quiz Engine API |
| title | string | No | Optional title (reserved for future use) |
API Endpoint Required
The component expects this endpoint:
GET {apiBaseUrl}/api/quiz-attempts/{attemptId}/resultsResponse format:
{
"attempt": {
"id": 123,
"quizId": 1,
"score": 80,
"totalQuestions": 10,
"correctAnswers": 8,
"timeTaken": 300,
"completedAt": "2025-01-02T10:00:00Z",
"answers": { "1": "selected_answer", "2": "another_answer" }
},
"questions": [
{
"id": 1,
"questionText": "What is 2+2?",
"questionType": "multiple_choice",
"options": ["3", "4", "5"],
"correctAnswer": "4",
"explanation": "Basic addition"
}
]
}Styling
The component uses 100% width to fill its parent container. Wrap it in a sized container to control dimensions:
<div style={{ maxWidth: '800px', margin: '0 auto' }}>
<AttemptViewer attemptId={123} apiBaseUrl="https://api.example.com" />
</div>Features
- Summary cards showing score, questions count, and time taken
- Detailed breakdown of each question with correct/incorrect indicators
- Explanations displayed for each question when available
- Purple theme (#6721b0) matching the QuizPlayer design
- Responsive layout that adapts to container width
License
MIT
