feat: Implement AI-powered audio response evaluation with score, keywords, and feedback, integrating it into the AudioResponsePlayer component.

This commit is contained in:
2026-01-21 17:05:11 -03:00
parent 00ae5ac16b
commit 360cf520e8
9 changed files with 254 additions and 67 deletions
@@ -12,6 +12,7 @@ import OrderingBlock from "@/components/blocks/OrderingBlock";
import ShortAnswerBlock from "@/components/blocks/ShortAnswerBlock";
import DocumentBlock from "@/components/blocks/DocumentBlock";
import VideoMarkerBlock from "@/components/blocks/VideoMarkerBlock";
import AudioResponseBlock from "@/components/blocks/AudioResponseBlock";
import {
Save,
X,
@@ -155,7 +156,7 @@ export default function LessonEditor({ params }: { params: { id: string; lessonI
}
};
const addBlock = (type: 'description' | 'media' | 'quiz' | 'fill-in-the-blanks' | 'matching' | 'ordering' | 'short-answer' | 'document' | 'video_marker') => {
const addBlock = (type: 'description' | 'media' | 'quiz' | 'fill-in-the-blanks' | 'matching' | 'ordering' | 'short-answer' | 'document' | 'video_marker' | 'audio-response') => {
const newBlock: Block = {
id: Math.random().toString(36).substr(2, 9),
type,
@@ -168,6 +169,7 @@ export default function LessonEditor({ params }: { params: { id: string; lessonI
...(type === 'short-answer' && { prompt: "Question?", correctAnswers: ["Answer"] }),
...(type === 'document' && { url: "", title: "" }),
...(type === 'video_marker' && { url: "", title: "Video Interactivo", markers: [] }),
...(type === 'audio-response' && { prompt: "Ask a question for the student to record their answer...", keywords: [], timeLimit: 60 }),
};
setBlocks([...blocks, newBlock]);
};
@@ -585,6 +587,17 @@ export default function LessonEditor({ params }: { params: { id: string; lessonI
onChange={(updates) => updateBlock(block.id, updates)}
/>
)}
{block.type === 'audio-response' && (
<AudioResponseBlock
id={block.id}
title={block.title}
prompt={block.prompt || ""}
keywords={block.keywords || []}
timeLimit={block.timeLimit}
editMode={editMode}
onChange={(updates) => updateBlock(block.id, updates)}
/>
)}
</div>
</div>
))}
@@ -657,6 +670,13 @@ export default function LessonEditor({ params }: { params: { id: string; lessonI
<span className="text-2xl group-hover:scale-110 transition-transform">📚</span>
<span className="text-[10px] font-bold uppercase tracking-widest text-gray-400">Reading</span>
</button>
<button
onClick={() => addBlock('audio-response')}
className="flex flex-col items-center gap-2 p-6 glass hover:border-purple-500/50 transition-all group w-32"
>
<span className="text-2xl group-hover:scale-110 transition-transform">🎤</span>
<span className="text-[10px] font-bold uppercase tracking-widest text-gray-400">Audio</span>
</button>
<div className="w-px h-12 bg-white/5"></div>