- Add AIReportSystem.js for detailed AI response capture and report generation - Add AIReportInterface.js UI component for report access and export - Integrate AI reporting into LLMValidator and SmartPreviewOrchestrator - Add missing modules to Application.js configuration (unifiedDRS, smartPreviewOrchestrator) - Create missing content/chapters/sbs.json for book metadata - Enhance Application.js with debug logging for module loading - Add multi-format export capabilities (text, HTML, JSON) - Implement automatic learning insights extraction from AI feedback - Add session management and performance tracking for AI reports 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
465 lines
17 KiB
HTML
465 lines
17 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="fr">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>🎓 Test DRS Unifié - Class Generator 2.0</title>
|
|
|
|
<!-- Styles -->
|
|
<link rel="stylesheet" href="src/styles/base.css">
|
|
<link rel="stylesheet" href="src/styles/components.css">
|
|
|
|
<style>
|
|
body {
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
min-height: 100vh;
|
|
margin: 0;
|
|
padding: 20px;
|
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
}
|
|
|
|
.test-container {
|
|
max-width: 800px;
|
|
margin: 0 auto;
|
|
background: white;
|
|
border-radius: 16px;
|
|
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
|
|
overflow: hidden;
|
|
}
|
|
|
|
.test-header {
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
color: white;
|
|
padding: 24px;
|
|
text-align: center;
|
|
}
|
|
|
|
.test-header h1 {
|
|
margin: 0 0 8px 0;
|
|
font-size: 2em;
|
|
}
|
|
|
|
.test-header p {
|
|
margin: 0;
|
|
opacity: 0.9;
|
|
font-size: 1.1em;
|
|
}
|
|
|
|
.test-content {
|
|
padding: 24px;
|
|
}
|
|
|
|
.test-controls {
|
|
display: flex;
|
|
gap: 12px;
|
|
margin-bottom: 24px;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.status {
|
|
padding: 12px;
|
|
border-radius: 8px;
|
|
margin: 16px 0;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.status.success {
|
|
background: #ecfdf5;
|
|
color: #065f46;
|
|
border: 1px solid #10b981;
|
|
}
|
|
|
|
.status.error {
|
|
background: #fef2f2;
|
|
color: #991b1b;
|
|
border: 1px solid #ef4444;
|
|
}
|
|
|
|
.status.loading {
|
|
background: #eff6ff;
|
|
color: #1e40af;
|
|
border: 1px solid #3b82f6;
|
|
}
|
|
|
|
.drs-container {
|
|
border: 2px dashed #e5e7eb;
|
|
border-radius: 12px;
|
|
padding: 20px;
|
|
min-height: 400px;
|
|
background: #fafafa;
|
|
text-align: center;
|
|
color: #6b7280;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.drs-container.active {
|
|
border-style: solid;
|
|
border-color: #3b82f6;
|
|
background: white;
|
|
text-align: left;
|
|
}
|
|
|
|
.empty-state {
|
|
font-size: 1.1em;
|
|
}
|
|
|
|
.debug-panel {
|
|
background: #f8fafc;
|
|
border: 1px solid #e2e8f0;
|
|
border-radius: 8px;
|
|
padding: 16px;
|
|
margin-top: 20px;
|
|
}
|
|
|
|
.debug-panel h3 {
|
|
margin: 0 0 12px 0;
|
|
color: #475569;
|
|
}
|
|
|
|
.debug-info {
|
|
font-family: monospace;
|
|
font-size: 12px;
|
|
color: #64748b;
|
|
background: white;
|
|
padding: 8px;
|
|
border-radius: 4px;
|
|
white-space: pre-wrap;
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.test-controls {
|
|
flex-direction: column;
|
|
}
|
|
|
|
.test-controls button {
|
|
width: 100%;
|
|
}
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="test-container">
|
|
<div class="test-header">
|
|
<h1>🎓 Test DRS Unifié</h1>
|
|
<p>Nouveau système DRS avec composants UI extraits</p>
|
|
</div>
|
|
|
|
<div class="test-content">
|
|
<!-- Controls -->
|
|
<div class="test-controls">
|
|
<button id="startTextBtn" class="btn btn-primary">📚 Start Text Exercise</button>
|
|
<button id="startAudioBtn" class="btn btn-secondary">🎵 Start Audio Exercise</button>
|
|
<button id="startImageBtn" class="btn btn-outline">🖼️ Start Image Exercise</button>
|
|
<button id="startGrammarBtn" class="btn btn-success">📝 Start Grammar Exercise</button>
|
|
<button id="resetBtn" class="btn btn-danger">🔄 Reset</button>
|
|
</div>
|
|
|
|
<!-- Status -->
|
|
<div id="status" class="status" style="display: none;"></div>
|
|
|
|
<!-- DRS Container -->
|
|
<div id="drsContainer" class="drs-container">
|
|
<div class="empty-state">
|
|
<h3>👆 Choisissez un type d'exercice</h3>
|
|
<p>Sélectionnez un bouton ci-dessus pour tester le DRS unifié</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Debug Panel -->
|
|
<div class="debug-panel">
|
|
<h3>🔍 Debug Info</h3>
|
|
<div id="debugInfo" class="debug-info">Ready to test...</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script type="module">
|
|
import UnifiedDRS from './src/DRS/UnifiedDRS.js';
|
|
import EventBus from './src/core/EventBus.js';
|
|
|
|
// Create mock ContentLoader
|
|
class MockContentLoader {
|
|
constructor() {
|
|
this.name = 'mockContentLoader';
|
|
}
|
|
|
|
async loadExercise(request) {
|
|
console.log('📚 Mock loading exercise:', request);
|
|
|
|
// Return mock exercise data based on type
|
|
const exercises = {
|
|
text: {
|
|
title: "Reading Comprehension",
|
|
type: "text",
|
|
steps: [
|
|
{
|
|
instruction: "Read the following passage and answer the question.",
|
|
text: "The sun is a star at the center of our solar system. It provides light and heat that makes life possible on Earth. The sun is about 4.6 billion years old and will continue to shine for another 5 billion years.",
|
|
question: "How old is the sun approximately?",
|
|
options: ["1 billion years", "4.6 billion years", "10 billion years", "100 million years"],
|
|
correct: 1,
|
|
hint: "Look for the specific number mentioned in the passage."
|
|
},
|
|
{
|
|
instruction: "Answer another question about the passage.",
|
|
question: "How much longer will the sun continue to shine?",
|
|
options: ["1 billion years", "3 billion years", "5 billion years", "10 billion years"],
|
|
correct: 2,
|
|
hint: "The passage mentions the sun will continue for another specific duration."
|
|
}
|
|
]
|
|
},
|
|
audio: {
|
|
title: "Listening Exercise",
|
|
type: "audio",
|
|
steps: [
|
|
{
|
|
instruction: "Listen to the audio and answer the question.",
|
|
audioUrl: "https://www.soundjay.com/misc/sounds/bell-ringing-05.wav",
|
|
transcript: "Hello, this is a test audio message. The weather today is sunny and warm.",
|
|
question: "What is the weather like today?",
|
|
options: ["Rainy", "Sunny and warm", "Cold", "Windy"],
|
|
correct: 1,
|
|
hint: "Listen carefully to the description of the weather."
|
|
}
|
|
]
|
|
},
|
|
image: {
|
|
title: "Image Analysis",
|
|
type: "image",
|
|
steps: [
|
|
{
|
|
instruction: "Look at the image and answer the question.",
|
|
imageUrl: "https://via.placeholder.com/400x300/667eea/ffffff?text=Beautiful+Sunset",
|
|
question: "What do you see in this image?",
|
|
options: ["Sunrise", "Sunset", "Night sky", "Storm"],
|
|
correct: 1,
|
|
hint: "Look at the colors and lighting in the image."
|
|
}
|
|
]
|
|
},
|
|
grammar: {
|
|
title: "Grammar Exercise",
|
|
type: "grammar",
|
|
steps: [
|
|
{
|
|
instruction: "Fill in the blanks with the correct words.",
|
|
sentence: "The cat _____ on the mat yesterday.",
|
|
question: "Complete the sentence with the correct past tense form.",
|
|
explanation: "Use the past tense of 'sit' which is 'sat'.",
|
|
correct: "sat",
|
|
hint: "Think about the past tense of the verb 'sit'."
|
|
},
|
|
{
|
|
instruction: "Choose the correct grammatical form.",
|
|
question: "Which sentence is grammatically correct?",
|
|
options: [
|
|
"I have went to the store",
|
|
"I have gone to the store",
|
|
"I have go to the store",
|
|
"I have going to the store"
|
|
],
|
|
correct: 1,
|
|
explanation: "The correct past participle of 'go' is 'gone', not 'went'.",
|
|
hint: "Remember the difference between past tense and past participle."
|
|
}
|
|
]
|
|
}
|
|
};
|
|
|
|
const exercise = exercises[request.subtype] || exercises.text;
|
|
|
|
// Simulate loading delay
|
|
await new Promise(resolve => setTimeout(resolve, 500));
|
|
|
|
return exercise;
|
|
}
|
|
}
|
|
|
|
// Initialize system
|
|
const eventBus = new EventBus();
|
|
const contentLoader = new MockContentLoader();
|
|
|
|
// Register mock content loader
|
|
eventBus.registerModule(contentLoader);
|
|
|
|
const unifiedDRS = new UnifiedDRS('unifiedDRS', {
|
|
eventBus,
|
|
contentLoader
|
|
});
|
|
|
|
// Register DRS module
|
|
eventBus.registerModule(unifiedDRS);
|
|
|
|
// Initialize
|
|
await unifiedDRS.init();
|
|
|
|
// Get DOM elements
|
|
const startTextBtn = document.getElementById('startTextBtn');
|
|
const startAudioBtn = document.getElementById('startAudioBtn');
|
|
const startImageBtn = document.getElementById('startImageBtn');
|
|
const startGrammarBtn = document.getElementById('startGrammarBtn');
|
|
const resetBtn = document.getElementById('resetBtn');
|
|
const status = document.getElementById('status');
|
|
const drsContainer = document.getElementById('drsContainer');
|
|
const debugInfo = document.getElementById('debugInfo');
|
|
|
|
// Utility functions
|
|
function showStatus(message, type = 'loading') {
|
|
status.textContent = message;
|
|
status.className = `status ${type}`;
|
|
status.style.display = 'block';
|
|
}
|
|
|
|
function hideStatus() {
|
|
status.style.display = 'none';
|
|
}
|
|
|
|
function updateDebug(info) {
|
|
const timestamp = new Date().toLocaleTimeString();
|
|
debugInfo.textContent = `[${timestamp}] ${info}`;
|
|
}
|
|
|
|
function activateDRSContainer() {
|
|
drsContainer.classList.add('active');
|
|
drsContainer.innerHTML = '';
|
|
}
|
|
|
|
function resetDRSContainer() {
|
|
drsContainer.classList.remove('active');
|
|
drsContainer.innerHTML = `
|
|
<div class="empty-state">
|
|
<h3>👆 Choisissez un type d'exercice</h3>
|
|
<p>Sélectionnez un bouton ci-dessus pour tester le DRS unifié</p>
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
// Event listeners
|
|
startTextBtn.addEventListener('click', async () => {
|
|
try {
|
|
showStatus('🚀 Starting text exercise...', 'loading');
|
|
updateDebug('Starting text exercise');
|
|
activateDRSContainer();
|
|
|
|
await unifiedDRS.start(drsContainer, {
|
|
type: 'text',
|
|
difficulty: 'medium'
|
|
});
|
|
|
|
showStatus('✅ Text exercise started successfully!', 'success');
|
|
updateDebug('Text exercise started successfully');
|
|
} catch (error) {
|
|
showStatus(`❌ Error: ${error.message}`, 'error');
|
|
updateDebug(`Error starting text exercise: ${error.message}`);
|
|
console.error('Error starting text exercise:', error);
|
|
}
|
|
});
|
|
|
|
startAudioBtn.addEventListener('click', async () => {
|
|
try {
|
|
showStatus('🚀 Starting audio exercise...', 'loading');
|
|
updateDebug('Starting audio exercise');
|
|
activateDRSContainer();
|
|
|
|
await unifiedDRS.start(drsContainer, {
|
|
type: 'audio',
|
|
difficulty: 'medium'
|
|
});
|
|
|
|
showStatus('✅ Audio exercise started successfully!', 'success');
|
|
updateDebug('Audio exercise started successfully');
|
|
} catch (error) {
|
|
showStatus(`❌ Error: ${error.message}`, 'error');
|
|
updateDebug(`Error starting audio exercise: ${error.message}`);
|
|
console.error('Error starting audio exercise:', error);
|
|
}
|
|
});
|
|
|
|
startImageBtn.addEventListener('click', async () => {
|
|
try {
|
|
showStatus('🚀 Starting image exercise...', 'loading');
|
|
updateDebug('Starting image exercise');
|
|
activateDRSContainer();
|
|
|
|
await unifiedDRS.start(drsContainer, {
|
|
type: 'image',
|
|
difficulty: 'medium'
|
|
});
|
|
|
|
showStatus('✅ Image exercise started successfully!', 'success');
|
|
updateDebug('Image exercise started successfully');
|
|
} catch (error) {
|
|
showStatus(`❌ Error: ${error.message}`, 'error');
|
|
updateDebug(`Error starting image exercise: ${error.message}`);
|
|
console.error('Error starting image exercise:', error);
|
|
}
|
|
});
|
|
|
|
startGrammarBtn.addEventListener('click', async () => {
|
|
try {
|
|
showStatus('🚀 Starting grammar exercise...', 'loading');
|
|
updateDebug('Starting grammar exercise');
|
|
activateDRSContainer();
|
|
|
|
await unifiedDRS.start(drsContainer, {
|
|
type: 'grammar',
|
|
difficulty: 'medium'
|
|
});
|
|
|
|
showStatus('✅ Grammar exercise started successfully!', 'success');
|
|
updateDebug('Grammar exercise started successfully');
|
|
} catch (error) {
|
|
showStatus(`❌ Error: ${error.message}`, 'error');
|
|
updateDebug(`Error starting grammar exercise: ${error.message}`);
|
|
console.error('Error starting grammar exercise:', error);
|
|
}
|
|
});
|
|
|
|
resetBtn.addEventListener('click', () => {
|
|
try {
|
|
showStatus('🔄 Resetting DRS...', 'loading');
|
|
updateDebug('Resetting DRS system');
|
|
|
|
resetDRSContainer();
|
|
hideStatus();
|
|
|
|
updateDebug('DRS system reset successfully');
|
|
} catch (error) {
|
|
showStatus(`❌ Reset error: ${error.message}`, 'error');
|
|
updateDebug(`Reset error: ${error.message}`);
|
|
console.error('Reset error:', error);
|
|
}
|
|
});
|
|
|
|
// Event listeners for DRS events
|
|
eventBus.on('drs:started', (event) => {
|
|
updateDebug(`Exercise started: ${event.data.type} (${event.data.steps} steps)`);
|
|
}, 'testPage');
|
|
|
|
eventBus.on('drs:step-completed', (event) => {
|
|
updateDebug(`Step ${event.data.step + 1}/${event.data.total} completed`);
|
|
}, 'testPage');
|
|
|
|
eventBus.on('drs:hint-used', (event) => {
|
|
updateDebug(`Hint used for step ${event.data.step + 1}`);
|
|
}, 'testPage');
|
|
|
|
eventBus.on('drs:completed', (event) => {
|
|
const stats = event.data.stats;
|
|
showStatus(`🎉 Exercise completed! Time: ${Math.round(stats.timeSpent / 1000)}s, Hints: ${stats.userStats.hints}`, 'success');
|
|
updateDebug(`Exercise completed - Time: ${Math.round(stats.timeSpent / 1000)}s, Hints: ${stats.userStats.hints}`);
|
|
}, 'testPage');
|
|
|
|
// Register test page with EventBus
|
|
eventBus.registerModule({ name: 'testPage' });
|
|
|
|
// Initial debug update
|
|
updateDebug('UnifiedDRS test page loaded and ready');
|
|
console.log('🎓 UnifiedDRS Test Page ready!');
|
|
</script>
|
|
</body>
|
|
</html> |