modificaciones de scorm reporte de calificacion y cambio de rutas absolutas a relativas
This commit is contained in:
@@ -186,6 +186,18 @@ El módulo SCORM (`src/scorm/scorm.ts`) implementa todas las funciones estándar
|
|||||||
|
|
||||||
> En desarrollo, `scorm-again` simula el `window.API` del LMS automáticamente.
|
> En desarrollo, `scorm-again` simula el `window.API` del LMS automáticamente.
|
||||||
|
|
||||||
|
### Integración con el flujo del juego
|
||||||
|
|
||||||
|
`useSCORM` se inicializa en `App.tsx` al montar la aplicación. Al terminar las 10 preguntas (`handleGameEnd`):
|
||||||
|
|
||||||
|
```ts
|
||||||
|
setScore(correctas * 10, 100, 0) // Escala el puntaje a 100
|
||||||
|
setLessonStatus(aprobado ? 'passed' : 'failed')
|
||||||
|
finishSCORM() // Envía session_time y cierra
|
||||||
|
```
|
||||||
|
|
||||||
|
> El score se envía escalado a 100 para que coincida con el `masteryscore: 80` del manifiesto.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🧩 Componente Button
|
## 🧩 Componente Button
|
||||||
@@ -233,6 +245,12 @@ Para publicar en un LMS (Moodle, Cornerstone, etc.):
|
|||||||
## 📋 Pendientes
|
## 📋 Pendientes
|
||||||
|
|
||||||
- [ ] Reemplazar categorías y preguntas de cultura general por el contenido real del cliente
|
- [ ] Reemplazar categorías y preguntas de cultura general por el contenido real del cliente
|
||||||
- [ ] Integrar `setScore` y `completeLesson` con SCORM al finalizar la actividad
|
|
||||||
- [ ] Pruebas en LMS real (Moodle)
|
|
||||||
- [ ] Definir diseño visual final (colores, logo, imágenes del cliente)
|
- [ ] Definir diseño visual final (colores, logo, imágenes del cliente)
|
||||||
|
|
||||||
|
## ✅ Resuelto
|
||||||
|
|
||||||
|
- [x] Integrar `setScore` y `setLessonStatus` con SCORM al finalizar la actividad
|
||||||
|
- [x] Llamar `finishSCORM` al terminar el juego
|
||||||
|
- [x] Configurar `base: './'` en Vite para rutas relativas en Moodle
|
||||||
|
- [x] Rutas de audios relativas (`./audios/...`) para compatibilidad con LMS
|
||||||
|
- [x] Pruebas en LMS real (Moodle)
|
||||||
|
|||||||
+7
-1
@@ -4,6 +4,8 @@ import Cover from './components/screens/Cover'
|
|||||||
import Game from './components/screens/Game'
|
import Game from './components/screens/Game'
|
||||||
import Result from './components/screens/Result'
|
import Result from './components/screens/Result'
|
||||||
import { consumirIntento, intentosAgotados } from './hooks/useIntentos'
|
import { consumirIntento, intentosAgotados } from './hooks/useIntentos'
|
||||||
|
import { setScore, setLessonStatus, finishSCORM } from './scorm/scorm'
|
||||||
|
import { useSCORM } from './hooks/useSCORM'
|
||||||
|
|
||||||
type Screen = 'cover' | 'game' | 'result'
|
type Screen = 'cover' | 'game' | 'result'
|
||||||
|
|
||||||
@@ -13,6 +15,7 @@ interface ResultState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
|
useSCORM()
|
||||||
const [screen, setScreen] = useState<Screen>(() =>
|
const [screen, setScreen] = useState<Screen>(() =>
|
||||||
intentosAgotados() ? 'result' : 'cover'
|
intentosAgotados() ? 'result' : 'cover'
|
||||||
)
|
)
|
||||||
@@ -26,7 +29,10 @@ export default function App() {
|
|||||||
setScreen('game')
|
setScreen('game')
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleGameEnd(aprobado: boolean) {
|
function handleGameEnd(aprobado: boolean, correctas: number) {
|
||||||
|
setScore(correctas * 10, 100, 0)
|
||||||
|
setLessonStatus(aprobado ? 'passed' : 'failed')
|
||||||
|
finishSCORM()
|
||||||
setResultState({ aprobado, sinIntentos: intentosAgotados() })
|
setResultState({ aprobado, sinIntentos: intentosAgotados() })
|
||||||
setScreen('result')
|
setScreen('result')
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -1,6 +1,6 @@
|
|||||||
export const AUDIOS = {
|
export const AUDIOS = {
|
||||||
click: '/audios/click.mp3',
|
click: './audios/click.mp3',
|
||||||
wheelSpin: '/audios/wheel-spin.mp3',
|
wheelSpin: './audios/wheel-spin.mp3',
|
||||||
correct: '/audios/feedback-correct.mpeg',
|
correct: './audios/feedback-correct.mpeg',
|
||||||
incorrect: '/audios/feedback-incorrect.mpeg',
|
incorrect: './audios/feedback-incorrect.mpeg',
|
||||||
} as const
|
} as const
|
||||||
|
|||||||
@@ -5,14 +5,14 @@ import QuestionModal from '../game/QuestionModal'
|
|||||||
import RuletaSVG from '../game/Ruleta/RuletaSVG'
|
import RuletaSVG from '../game/Ruleta/RuletaSVG'
|
||||||
|
|
||||||
interface GameProps {
|
interface GameProps {
|
||||||
onEnd: (aprobado: boolean) => void
|
onEnd: (aprobado: boolean, correctas: number) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Game({ onEnd }: GameProps) {
|
export default function Game({ onEnd }: GameProps) {
|
||||||
const { estado, categorias, girar, responder, cerrarFeedback, MAX_PREGUNTAS } = useRuleta()
|
const { estado, categorias, girar, responder, cerrarFeedback, MAX_PREGUNTAS } = useRuleta()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (estado.completado) onEnd(estado.aprobado)
|
if (estado.completado) onEnd(estado.aprobado, estado.correctas)
|
||||||
}, [estado.completado])
|
}, [estado.completado])
|
||||||
|
|
||||||
function handleGirar() {
|
function handleGirar() {
|
||||||
|
|||||||
@@ -4,4 +4,5 @@ import tailwindcss from '@tailwindcss/vite'
|
|||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [react(), tailwindcss()],
|
plugins: [react(), tailwindcss()],
|
||||||
|
base: './',
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user