feat: Puente Mayúscula-Minúscula + TTS SpeechSynthesis + E2E fixes
This commit is contained in:
@@ -0,0 +1,235 @@
|
||||
import type { Stage } from '../types'
|
||||
|
||||
type ConInfo = {
|
||||
letra: string
|
||||
palabra: string
|
||||
emoji: string
|
||||
silabas: string[]
|
||||
gesto: string
|
||||
}
|
||||
|
||||
const consonantes: ConInfo[] = [
|
||||
{ letra: 'M', palabra: 'MAMÁ', emoji: '👩', silabas: ['MA', 'ME', 'MI', 'MO', 'MU'], gesto: 'Manos en la boca como mmm' },
|
||||
{ letra: 'P', palabra: 'PAPÁ', emoji: '👨', silabas: ['PA', 'PE', 'PI', 'PO', 'PU'], gesto: 'Manos que abren y cierran como pompa' },
|
||||
{ letra: 'L', palabra: 'LUNA', emoji: '🌙', silabas: ['LA', 'LE', 'LI', 'LO', 'LU'], gesto: 'Lengua arriba como lámpara' },
|
||||
{ letra: 'S', palabra: 'SOL', emoji: '☀️', silabas: ['SA', 'SE', 'SI', 'SO', 'SU'], gesto: 'Dedos como serpiente sss' },
|
||||
{ letra: 'T', palabra: 'TASA', emoji: '☕', silabas: ['TA', 'TE', 'TI', 'TO', 'TU'], gesto: 'Golpecito con la mano' },
|
||||
{ letra: 'N', palabra: 'NIDO', emoji: '🪺', silabas: ['NA', 'NE', 'NI', 'NO', 'NU'], gesto: 'Nariz como nido' },
|
||||
{ letra: 'D', palabra: 'DEDO', emoji: '👉', silabas: ['DA', 'DE', 'DI', 'DO', 'DU'], gesto: 'Dedo señalando' },
|
||||
{ letra: 'R', palabra: 'RATÓN', emoji: '🐭', silabas: ['RA', 'RE', 'RI', 'RO', 'RU'], gesto: 'Lengua que vibra como rrr' },
|
||||
]
|
||||
|
||||
const exercises: any[] = []
|
||||
|
||||
for (const con of consonantes) {
|
||||
// 1. Presentación con gesto
|
||||
exercises.push({
|
||||
id: `lec4-${con.letra.toLowerCase()}-gesto`,
|
||||
stage: 4,
|
||||
skillCode: `consonante-${con.letra.toLowerCase()}`,
|
||||
type: 'sensibilizacion',
|
||||
prerequisites: con.letra === 'M' ? ['lec3-u-completa'] : [`lec4-${consonantes[consonantes.indexOf(con) - 1].letra.toLowerCase()}-completa`],
|
||||
content: {
|
||||
instruction: `Hacé así para la ${con.letra}: ${con.gesto}`,
|
||||
audioText: `Esta es la letra ${con.letra}. ${con.palabra}. ${con.silabas[0].toLowerCase()}`,
|
||||
emoji: con.emoji,
|
||||
},
|
||||
functionalContext: `Conocer el gesto asociado a la consonante ${con.letra}.`,
|
||||
})
|
||||
|
||||
// 2. Reconocer la consonante
|
||||
exercises.push({
|
||||
id: `lec4-${con.letra.toLowerCase()}-reconocer`,
|
||||
stage: 4,
|
||||
skillCode: `consonante-${con.letra.toLowerCase()}`,
|
||||
type: 'eleccion',
|
||||
prerequisites: [`lec4-${con.letra.toLowerCase()}-gesto`],
|
||||
content: {
|
||||
instruction: `Señalá la letra ${con.letra}`,
|
||||
text: `Buscá la ${con.letra}`,
|
||||
audioText: `¿Dónde está la ${con.letra}?`,
|
||||
options: [
|
||||
{ label: con.letra, correct: true, id: con.letra.toLowerCase() },
|
||||
...consonantes.filter(c => c.letra !== con.letra).slice(0, 3).map(c => ({ label: c.letra, correct: false, id: c.letra.toLowerCase() })),
|
||||
],
|
||||
emoji: con.emoji,
|
||||
},
|
||||
functionalContext: `Reconocer visualmente la consonante ${con.letra}.`,
|
||||
errorType: 'confusion-letra',
|
||||
})
|
||||
|
||||
// 3. Discriminación auditiva de la sílaba
|
||||
exercises.push({
|
||||
id: `lec4-${con.letra.toLowerCase()}-auditiva`,
|
||||
stage: 4,
|
||||
skillCode: `consonante-${con.letra.toLowerCase()}`,
|
||||
type: 'conciencia',
|
||||
prerequisites: [`lec4-${con.letra.toLowerCase()}-reconocer`],
|
||||
content: {
|
||||
instruction: `Escuchá. ¿Cuál suena como ${con.silabas[0]}?`,
|
||||
audioText: `${con.silabas[0]}... ${con.silabas[0]}... como ${con.palabra}`,
|
||||
options: [
|
||||
{ label: con.silabas[0], correct: true, id: con.silabas[0].toLowerCase() },
|
||||
...consonantes.filter(c => c.letra !== con.letra).slice(0, 2).map(c => ({ label: c.silabas[0], correct: false, id: c.silabas[0].toLowerCase() })),
|
||||
],
|
||||
emoji: '👂',
|
||||
},
|
||||
functionalContext: `Discriminar auditivamente la sílaba ${con.silabas[0]}.`,
|
||||
errorType: 'discriminacion-auditiva',
|
||||
})
|
||||
|
||||
// 4. Emparejar sílaba con vocal
|
||||
for (let vi = 1; vi < con.silabas.length; vi++) {
|
||||
const sil = con.silabas[vi]
|
||||
const vocal = sil[1]
|
||||
const vocales = ['A', 'E', 'I', 'O', 'U'].filter(v => v !== vocal)
|
||||
exercises.push({
|
||||
id: `lec4-${con.letra.toLowerCase()}-silaba-${sil.toLowerCase()}`,
|
||||
stage: 4,
|
||||
skillCode: `consonante-${con.letra.toLowerCase()}-silabas`,
|
||||
type: 'eleccion',
|
||||
prerequisites: [`lec4-${con.letra.toLowerCase()}-auditiva`, `lec4-${con.letra.toLowerCase()}-silaba-${con.silabas[vi - 1].toLowerCase()}`],
|
||||
content: {
|
||||
instruction: `¿Cuál es ${sil}?`,
|
||||
text: sil,
|
||||
audioText: `${sil}... como ${con.palabra.toLowerCase()}`,
|
||||
options: [
|
||||
{ label: sil, correct: true, id: sil.toLowerCase() },
|
||||
{ label: `${con.letra}${vocales[0]}`, correct: false, id: `${con.letra}${vocales[0]}`.toLowerCase() },
|
||||
{ label: `${con.letra}${vocales[1]}`, correct: false, id: `${con.letra}${vocales[1]}`.toLowerCase() },
|
||||
],
|
||||
emoji: con.emoji,
|
||||
},
|
||||
functionalContext: `Leer la sílaba ${sil}.`,
|
||||
errorType: 'confusion-letra',
|
||||
})
|
||||
}
|
||||
|
||||
// 5. Palabra con la consonante
|
||||
exercises.push({
|
||||
id: `lec4-${con.letra.toLowerCase()}-palabra`,
|
||||
stage: 4,
|
||||
skillCode: `consonante-${con.letra.toLowerCase()}`,
|
||||
type: 'palabra',
|
||||
prerequisites: [`lec4-${con.letra.toLowerCase()}-silaba-${con.silabas[con.silabas.length - 1].toLowerCase()}`],
|
||||
content: {
|
||||
instruction: `¿Cuál palabra empieza con ${con.letra}?`,
|
||||
audioText: `${con.palabra} empieza con ${con.letra}`,
|
||||
imageEmoji: con.emoji,
|
||||
options: [
|
||||
{ label: con.palabra, correct: true, id: con.palabra.toLowerCase() },
|
||||
{ label: 'CASA', correct: false, id: 'casa' },
|
||||
{ label: 'GATO', correct: false, id: 'gato' },
|
||||
{ label: 'Escuchar 👂', correct: false, id: 'escuchar' },
|
||||
],
|
||||
},
|
||||
functionalContext: `Asociar la consonante ${con.letra} con una palabra significativa.`,
|
||||
errorType: 'discriminacion-auditiva',
|
||||
})
|
||||
|
||||
// 6. Final: repaso completo
|
||||
exercises.push({
|
||||
id: `lec4-${con.letra.toLowerCase()}-completa`,
|
||||
stage: 4,
|
||||
skillCode: `consonante-${con.letra.toLowerCase()}`,
|
||||
type: 'eleccion',
|
||||
prerequisites: [`lec4-${con.letra.toLowerCase()}-palabra`],
|
||||
content: {
|
||||
instruction: `¡Repaso! Señalá la letra ${con.letra}`,
|
||||
audioText: `Buscá la ${con.letra}`,
|
||||
options: [
|
||||
{ label: con.letra, correct: true, id: con.letra.toLowerCase() },
|
||||
...consonantes.filter(c => c.letra !== con.letra).slice(0, 3).map(c => ({ label: c.letra, correct: false, id: c.letra.toLowerCase() })),
|
||||
],
|
||||
emoji: con.emoji,
|
||||
},
|
||||
functionalContext: `Consolidar reconocimiento de la consonante ${con.letra}.`,
|
||||
errorType: 'confusion-letra',
|
||||
})
|
||||
}
|
||||
|
||||
// Cross-consonant discrimination exercises
|
||||
exercises.push({
|
||||
id: 'lec4-mix-mp',
|
||||
stage: 4,
|
||||
skillCode: 'consonante-discriminacion',
|
||||
type: 'eleccion',
|
||||
prerequisites: ['lec4-m-completa', 'lec4-p-completa'],
|
||||
content: {
|
||||
instruction: 'Señalá la M',
|
||||
options: [
|
||||
{ label: 'M', correct: true, id: 'm' },
|
||||
{ label: 'P', correct: false, id: 'p' },
|
||||
{ label: 'L', correct: false, id: 'l' },
|
||||
],
|
||||
emoji: '🔤',
|
||||
},
|
||||
functionalContext: 'Discriminar entre M y P.',
|
||||
errorType: 'confusion-letra',
|
||||
})
|
||||
|
||||
exercises.push({
|
||||
id: 'lec4-mix-st',
|
||||
stage: 4,
|
||||
skillCode: 'consonante-discriminacion',
|
||||
type: 'eleccion',
|
||||
prerequisites: ['lec4-s-completa', 'lec4-t-completa'],
|
||||
content: {
|
||||
instruction: 'Señalá la T',
|
||||
options: [
|
||||
{ label: 'S', correct: false, id: 's' },
|
||||
{ label: 'T', correct: true, id: 't' },
|
||||
{ label: 'N', correct: false, id: 'n' },
|
||||
],
|
||||
emoji: '🔤',
|
||||
},
|
||||
functionalContext: 'Discriminar entre S y T.',
|
||||
errorType: 'confusion-letra',
|
||||
})
|
||||
|
||||
exercises.push({
|
||||
id: 'lec4-mix-ld',
|
||||
stage: 4,
|
||||
skillCode: 'consonante-discriminacion',
|
||||
type: 'eleccion',
|
||||
prerequisites: ['lec4-l-completa', 'lec4-d-completa'],
|
||||
content: {
|
||||
instruction: 'Señalá la D',
|
||||
options: [
|
||||
{ label: 'L', correct: false, id: 'l' },
|
||||
{ label: 'D', correct: true, id: 'd' },
|
||||
{ label: 'R', correct: false, id: 'r' },
|
||||
],
|
||||
emoji: '🔤',
|
||||
},
|
||||
functionalContext: 'Discriminar entre L y D.',
|
||||
errorType: 'confusion-letra',
|
||||
})
|
||||
|
||||
exercises.push({
|
||||
id: 'lec4-mix-nr',
|
||||
stage: 4,
|
||||
skillCode: 'consonante-discriminacion',
|
||||
type: 'eleccion',
|
||||
prerequisites: ['lec4-n-completa', 'lec4-r-completa'],
|
||||
content: {
|
||||
instruction: 'Señalá la R',
|
||||
options: [
|
||||
{ label: 'N', correct: false, id: 'n' },
|
||||
{ label: 'R', correct: true, id: 'r' },
|
||||
{ label: 'M', correct: false, id: 'm' },
|
||||
],
|
||||
emoji: '🔤',
|
||||
},
|
||||
functionalContext: 'Discriminar entre N y R.',
|
||||
errorType: 'confusion-letra',
|
||||
})
|
||||
|
||||
const stage: Stage = {
|
||||
id: 4,
|
||||
name: 'Consonantes M-P-L-S-T-N-D-R',
|
||||
description: 'Aprender las consonantes M, P, L, S, T, N, D, R con gestos, sílabas, y palabras significativas.',
|
||||
exercises,
|
||||
}
|
||||
|
||||
export default stage
|
||||
Reference in New Issue
Block a user