last message

This commit is contained in:
2026-04-25 20:48:31 +02:00
parent c420d539da
commit fadd28439e
5 changed files with 107 additions and 2 deletions

View File

@@ -225,6 +225,11 @@ function TutorApp({ currentUser, onLogout }) {
[voiceProfiles, selectedVoiceProfileId]
)
const latestAssistantMessage = useMemo(
() => [...messages].reverse().find((message) => message.role === 'assistant') || null,
[messages]
)
const averageScore = useMemo(() => {
if (!progress.length) return 0
const total = progress.reduce((sum, item) => sum + item.mastery_score, 0)
@@ -260,6 +265,9 @@ function TutorApp({ currentUser, onLogout }) {
useEffect(() => {
if (selectedStudentId) {
loadProgress(selectedStudentId)
loadMessages(selectedStudentId)
} else {
setMessages([])
}
}, [selectedStudentId])
@@ -409,7 +417,8 @@ function TutorApp({ currentUser, onLogout }) {
answer: assessmentAnswer,
}),
})
appendMessage('assistant', `Quiz: ${data.feedback}`)
appendMessage('user', `Reponse au mini-test: ${assessmentAnswer}`)
appendMessage('assistant', data.feedback)
speak(data.feedback)
setAssessment(null)
setAssessmentAnswer('')
@@ -432,6 +441,23 @@ function TutorApp({ currentUser, onLogout }) {
setSpeaking(false)
}
async function loadMessages(studentId) {
try {
setErrorMessage('')
const data = await apiFetch(`/students/${studentId}/messages?limit=80`)
setMessages(
(data || []).map((message) => ({
id: message.id,
role: message.role,
content: message.content,
created_at: message.created_at,
}))
)
} catch (error) {
setErrorMessage(error.message || 'Impossible de charger la conversation.')
}
}
async function finishSpeechPlayback(debugMessage) {
setSpeaking(false)
if (audioPlaybackUrlRef.current) {
@@ -863,6 +889,17 @@ function TutorApp({ currentUser, onLogout }) {
</div>
</div>
<section className="instruction-stage">
<span className="stage-label">Derniere instruction</span>
{latestAssistantMessage ? (
<p>{latestAssistantMessage.content}</p>
) : (
<p className="muted">
Demarre la seance pour afficher ici la consigne de Professeur TOP.
</p>
)}
</section>
<section className="messages">
{messages.length === 0 && <p className="muted">Le dialogue apparaîtra ici.</p>}
{messages.map((message) => (

View File

@@ -58,9 +58,32 @@ button:disabled { opacity: 0.5; cursor: not-allowed; }
color: #64748b;
font-size: 0.95rem;
}
.instruction-stage {
min-height: 180px;
display: flex;
flex-direction: column;
justify-content: center;
gap: 0.75rem;
background: #eef6ff;
border: 1px solid #cfe4ff;
border-radius: 20px;
padding: 1.25rem;
}
.instruction-stage p {
margin: 0;
font-size: 1.25rem;
line-height: 1.5;
white-space: pre-wrap;
}
.stage-label {
color: #2563eb;
font-size: 0.85rem;
font-weight: 700;
text-transform: uppercase;
}
.messages {
flex: 1;
min-height: 360px;
min-height: 220px;
overflow: auto;
background: #f8fafc;
border-radius: 20px;