Spaces:
Sleeping
Sleeping
Commit ·
f3e9b82
1
Parent(s): e3638cc
when just one right option is left and user has already given 3 wrong an
Browse files
src/components/chatbot/chatbot.tsx
CHANGED
|
@@ -98,7 +98,7 @@ export function Chatbot({ imageDataUri, journeyTitle }: ChatbotProps) {
|
|
| 98 |
const handleOptionSelect = async (option: string, isCorrect: boolean) => {
|
| 99 |
if (!currentMCQ) return;
|
| 100 |
|
| 101 |
-
setIsAwaitingAnswer(false);
|
| 102 |
|
| 103 |
addMessage({
|
| 104 |
sender: 'user',
|
|
@@ -122,31 +122,55 @@ export function Chatbot({ imageDataUri, journeyTitle }: ChatbotProps) {
|
|
| 122 |
addMessage({ sender: 'ai', type: 'error', text: `Sorry, I couldn't provide an explanation for that. ${errorMsg}` });
|
| 123 |
}
|
| 124 |
setHasAnsweredCorrectly(true);
|
| 125 |
-
setIncorrectAttempts([]);
|
| 126 |
setIsLoading(false);
|
| 127 |
} else {
|
| 128 |
-
|
|
|
|
| 129 |
setIsLoading(true);
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
|
|
|
|
|
|
| 136 |
});
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 147 |
}
|
| 148 |
-
setHasAnsweredCorrectly(false);
|
| 149 |
-
setIsAwaitingAnswer(true);
|
| 150 |
setIsLoading(false);
|
| 151 |
}
|
| 152 |
};
|
|
@@ -165,7 +189,8 @@ export function Chatbot({ imageDataUri, journeyTitle }: ChatbotProps) {
|
|
| 165 |
currentMCQ &&
|
| 166 |
msg.mcq.mcq === currentMCQ.mcq &&
|
| 167 |
JSON.stringify(msg.mcq.options) === JSON.stringify(currentMCQ.options);
|
| 168 |
-
|
|
|
|
| 169 |
const lastInstanceOfCurrentMCQIndex = messages.findLastIndex(
|
| 170 |
(m) =>
|
| 171 |
m.type === 'mcq' &&
|
|
@@ -175,21 +200,25 @@ export function Chatbot({ imageDataUri, journeyTitle }: ChatbotProps) {
|
|
| 175 |
JSON.stringify(m.mcq.options) === JSON.stringify(currentMCQ.options)
|
| 176 |
);
|
| 177 |
|
|
|
|
|
|
|
|
|
|
| 178 |
const shouldThisMessageBeInteractive =
|
| 179 |
isThisMessageTheCurrentMCQ &&
|
| 180 |
index === lastInstanceOfCurrentMCQIndex &&
|
| 181 |
-
isAwaitingAnswer &&
|
| 182 |
!hasAnsweredCorrectly;
|
| 183 |
|
| 184 |
return (
|
| 185 |
<ChatMessage
|
| 186 |
key={msg.id}
|
| 187 |
message={msg}
|
| 188 |
-
activeMCQ={currentMCQ}
|
| 189 |
isAwaitingActiveMCQAnswer={shouldThisMessageBeInteractive}
|
| 190 |
onOptionSelectActiveMCQ={handleOptionSelect}
|
| 191 |
incorrectAttemptsForMCQ={
|
| 192 |
-
isThisMessageTheCurrentMCQ
|
|
|
|
| 193 |
? incorrectAttempts
|
| 194 |
: []
|
| 195 |
}
|
|
@@ -225,7 +254,7 @@ export function Chatbot({ imageDataUri, journeyTitle }: ChatbotProps) {
|
|
| 225 |
{!imageDataUri && !isLoading && (
|
| 226 |
<p className="text-center text-sm text-muted-foreground">Loading image, please wait...</p>
|
| 227 |
)}
|
| 228 |
-
{!currentMCQ && !isLoading && messages.length > 0 && messages[messages.length -1]?.type !== 'error' && (
|
| 229 |
<p className="text-center text-sm text-muted-foreground">Loading first question...</p>
|
| 230 |
)}
|
| 231 |
</div>
|
|
|
|
| 98 |
const handleOptionSelect = async (option: string, isCorrect: boolean) => {
|
| 99 |
if (!currentMCQ) return;
|
| 100 |
|
| 101 |
+
setIsAwaitingAnswer(false); // User has submitted an answer
|
| 102 |
|
| 103 |
addMessage({
|
| 104 |
sender: 'user',
|
|
|
|
| 122 |
addMessage({ sender: 'ai', type: 'error', text: `Sorry, I couldn't provide an explanation for that. ${errorMsg}` });
|
| 123 |
}
|
| 124 |
setHasAnsweredCorrectly(true);
|
| 125 |
+
setIncorrectAttempts([]); // Clear attempts on correct answer
|
| 126 |
setIsLoading(false);
|
| 127 |
} else {
|
| 128 |
+
const updatedIncorrectAttempts = [...incorrectAttempts, option];
|
| 129 |
+
setIncorrectAttempts(updatedIncorrectAttempts);
|
| 130 |
setIsLoading(true);
|
| 131 |
+
|
| 132 |
+
if (updatedIncorrectAttempts.length >= currentMCQ.options.length - 1) {
|
| 133 |
+
// All incorrect options have been tried
|
| 134 |
+
addMessage({
|
| 135 |
+
sender: 'ai',
|
| 136 |
+
type: 'feedback',
|
| 137 |
+
text: `It looks like you've tried the other options. The correct answer is "${currentMCQ.correctAnswer}".`,
|
| 138 |
+
isCorrect: true, // Marking as 'correct' flow for styling purposes of feedback
|
| 139 |
});
|
| 140 |
+
try {
|
| 141 |
+
const explanationResult = await explainCorrectAnswer({
|
| 142 |
+
question: currentMCQ.mcq,
|
| 143 |
+
options: currentMCQ.options,
|
| 144 |
+
correctAnswer: currentMCQ.correctAnswer,
|
| 145 |
+
});
|
| 146 |
+
addMessage({ sender: 'ai', type: 'feedback', text: explanationResult.explanation, isCorrect: true });
|
| 147 |
+
} catch (error) {
|
| 148 |
+
console.error("Error fetching correct answer explanation after exhausting options:", error);
|
| 149 |
+
const errorMsg = error instanceof Error ? error.message : "An unknown error occurred";
|
| 150 |
+
addMessage({ sender: 'ai', type: 'error', text: `Sorry, I couldn't provide an explanation for that. ${errorMsg}` });
|
| 151 |
+
}
|
| 152 |
+
setHasAnsweredCorrectly(true);
|
| 153 |
+
setIncorrectAttempts([]); // Clear attempts as the question is resolved
|
| 154 |
+
} else {
|
| 155 |
+
// Still more options to try
|
| 156 |
+
try {
|
| 157 |
+
const explanationResult = await explainIncorrectAnswer({
|
| 158 |
+
question: currentMCQ.mcq,
|
| 159 |
+
options: currentMCQ.options,
|
| 160 |
+
selectedAnswer: option,
|
| 161 |
+
correctAnswer: currentMCQ.correctAnswer,
|
| 162 |
+
});
|
| 163 |
+
addMessage({ sender: 'ai', type: 'feedback', text: explanationResult.explanation, isCorrect: false });
|
| 164 |
+
addMessage({ sender: 'ai', type: 'mcq', mcq: currentMCQ }); // Re-post the same MCQ for another attempt
|
| 165 |
+
} catch (error) {
|
| 166 |
+
console.error("Error fetching explanation for incorrect answer:", error);
|
| 167 |
+
const errorMsg = error instanceof Error ? error.message : "An unknown error occurred";
|
| 168 |
+
addMessage({ sender: 'ai', type: 'error', text: `Sorry, I couldn't explain that. ${errorMsg}` });
|
| 169 |
+
addMessage({ sender: 'ai', type: 'feedback', text: "That's not quite right. Try again!", isCorrect: false });
|
| 170 |
+
addMessage({ sender: 'ai', type: 'mcq', mcq: currentMCQ }); // If explanation fetch fails, still re-post MCQ
|
| 171 |
+
}
|
| 172 |
+
setIsAwaitingAnswer(true); // Allow another answer on the re-posted MCQ
|
| 173 |
}
|
|
|
|
|
|
|
| 174 |
setIsLoading(false);
|
| 175 |
}
|
| 176 |
};
|
|
|
|
| 189 |
currentMCQ &&
|
| 190 |
msg.mcq.mcq === currentMCQ.mcq &&
|
| 191 |
JSON.stringify(msg.mcq.options) === JSON.stringify(currentMCQ.options);
|
| 192 |
+
|
| 193 |
+
// Find the index of the last message that is the current active MCQ
|
| 194 |
const lastInstanceOfCurrentMCQIndex = messages.findLastIndex(
|
| 195 |
(m) =>
|
| 196 |
m.type === 'mcq' &&
|
|
|
|
| 200 |
JSON.stringify(m.mcq.options) === JSON.stringify(currentMCQ.options)
|
| 201 |
);
|
| 202 |
|
| 203 |
+
// This specific message should be interactive if it's the current MCQ,
|
| 204 |
+
// it's the *last* instance of that MCQ in the chat,
|
| 205 |
+
// and we are awaiting an answer for it and it hasn't been correctly answered yet.
|
| 206 |
const shouldThisMessageBeInteractive =
|
| 207 |
isThisMessageTheCurrentMCQ &&
|
| 208 |
index === lastInstanceOfCurrentMCQIndex &&
|
| 209 |
+
isAwaitingAnswer &&
|
| 210 |
!hasAnsweredCorrectly;
|
| 211 |
|
| 212 |
return (
|
| 213 |
<ChatMessage
|
| 214 |
key={msg.id}
|
| 215 |
message={msg}
|
| 216 |
+
activeMCQ={currentMCQ} // Pass currentMCQ to know its structure
|
| 217 |
isAwaitingActiveMCQAnswer={shouldThisMessageBeInteractive}
|
| 218 |
onOptionSelectActiveMCQ={handleOptionSelect}
|
| 219 |
incorrectAttemptsForMCQ={
|
| 220 |
+
isThisMessageTheCurrentMCQ && // Only pass attempts for the current, active MCQ instance
|
| 221 |
+
index === lastInstanceOfCurrentMCQIndex
|
| 222 |
? incorrectAttempts
|
| 223 |
: []
|
| 224 |
}
|
|
|
|
| 254 |
{!imageDataUri && !isLoading && (
|
| 255 |
<p className="text-center text-sm text-muted-foreground">Loading image, please wait...</p>
|
| 256 |
)}
|
| 257 |
+
{!currentMCQ && !isLoading && messages.length > 0 && messages[messages.length -1]?.type !== 'error' && messages[messages.length -1]?.type !== 'text' && (
|
| 258 |
<p className="text-center text-sm text-muted-foreground">Loading first question...</p>
|
| 259 |
)}
|
| 260 |
</div>
|