function ExerciseMaterialLinks({exercise}){ const materials=[]; const add=(src,label)=>{src=window.LiveCatalog?.media(src)||src;if(typeof src==='string'&&src&&!materials.some(m=>m.src===src))materials.push({src,label});}; if(exercise.type==='reaction'){ const source=exercise.cardMedia||exercise.media||(exercise.token?(window.REACTION_CONFIG?.BASE_DIR||'DINAMICS/JUEGOS/MATE/')+exercise.token+'.mp4':''); if(typeof source==='string')add(source.replace('DINAMICS/JUEGOS/MATE/','DINAMICS/JUEGOS/WEB/MATE/'),'Ver material completo'); } else add(typeof exercise.media==='string'?exercise.media:exercise.media?.src,'Ver imagen completa'); const slotId=String(exercise.id||'').replace(/^slot:/,''); const activity=window.REAL_CONSTRUCTION_CONFIG?.activities?.[slotId]; const labels={affirmative:'Ver imagen afirmativa',negative:'Ver GIF negativo',question:'Ver GIF de pregunta'}; if(activity)Object.entries(activity).forEach(([kind,spec])=>add(window.REAL_CONSTRUCTION_CONFIG.images?.[spec.image]?.src,labels[kind]||'Ver imagen completa')); if(!materials.length)return null; return
{materials.map(({src,label})=>{label} ↗)}
; } function ExistingExerciseCatalog({user,baseUrl,admin,topics}){ const [items,setItems]=React.useState([]),[type,setType]=React.useState(''),[topic,setTopic]=React.useState(''),[diff,setDiff]=React.useState(''),[search,setSearch]=React.useState(''),[edit,setEdit]=React.useState(null),[payload,setPayload]=React.useState({}),[busy,setBusy]=React.useState(false),[error,setError]=React.useState(''),[notice,setNotice]=React.useState(''); const request=(route,options)=>window.TeacherRoomClient.request(baseUrl,user,route,options); async function load(){const data=await request('/authoring/legacy');setItems(data.items);} React.useEffect(()=>{let live=true;request('/authoring/legacy').then(data=>{if(live)setItems(data.items);}).catch(e=>{if(live)setError(e.message);});return()=>{live=false;};},[user.id,baseUrl]); const names={reaction:'Reaction',zero:'Zero Error',zeroError:'Zero Error · Casilla',mirror:'Mirror Reflection',alien:'Alien Contact',alienContact:'Mirror Reflection · Casilla',special_technique:'Special Technique',video:'Clase en video',aiExam:'Examen IA',activity:'Actividad de Paso a Paso'}; const difficulties={f:'Fácil',m:'Medio',d:'Difícil'}; const topicName=id=>id?(id+' · '+(topics.find(t=>t.id===id)?.name||'Topic no identificado')):'No declarado'; function open(item){setEdit(item);setPayload({learning:item.learning,connectedTopics:[...item.connectedTopics],...(item.type==='zero'?{question:item.question,options:item.options.map(o=>({...o})),correct:item.correct}:{})});setError('');setNotice('');} async function save(e){e.preventDefault();if(busy)return;setBusy(true);setError('');setNotice('');try{await request('/authoring/legacy',{method:'POST',body:JSON.stringify({id:edit.id,version:edit.version,sourceVersion:edit.sourceVersion,payload})});setEdit(null);await load();setNotice('Corrección guardada. Los alumnos la reciben al recargar con esta API activada.');}catch(e){setError(e.message);}finally{setBusy(false);}} const visible=items.filter(item=>(!type||item.type===type)&&(!topic||item.primaryTopic===topic||item.connectedTopics.includes(topic))&&(!diff||item.difficulty===diff||item.difficulties?.includes(diff))&&(item.title+' '+item.id).toLowerCase().includes(search.toLowerCase())); return

Ejercicios existentes

Los IDs, el progreso y los archivos de origen se conservan. Los campos que requieren migración aparecen bloqueados.

{error&&

{error}

}{notice&&

{notice}

}

{visible.length} de {items.length} registros

{edit&&

Editar: {edit.title}

Principal: {topicName(edit.primaryTopic)}. {edit.restriction}

Topics secundarios{payload.connectedTopics.map(id=>

{topicName(id)}

)}
{edit.type==='zero'&&
Corregir pregunta y opciones