fix: auto-submit answer on timeout instead of blocking

- Timeout triggers forced submission of current answer (or empty)
- Prevents assessment from hanging when time expires
- autoSubmitted flag prevents duplicate submissions
This commit is contained in:
Developer
2026-05-21 14:32:01 +08:00
parent 02f4ab23f7
commit 9303d7ac64
+13 -6
View File
@@ -53,6 +53,7 @@ export const AssessmentView: React.FC<AssessmentViewProps> = ({
const [selectedTemplate, setSelectedTemplate] = useState<string | null>(null); const [selectedTemplate, setSelectedTemplate] = useState<string | null>(null);
const [timeCheck, setTimeCheck] = useState<{ totalTimeRemaining: number; questionTimeRemaining: number; isTotalTimeout: boolean; isQuestionTimeout: boolean } | null>(null); const [timeCheck, setTimeCheck] = useState<{ totalTimeRemaining: number; questionTimeRemaining: number; isTotalTimeout: boolean; isQuestionTimeout: boolean } | null>(null);
const [selectedChoice, setSelectedChoice] = useState<string | null>(null); const [selectedChoice, setSelectedChoice] = useState<string | null>(null);
const [autoSubmitted, setAutoSubmitted] = useState(false);
const isTimedOut = timeCheck?.isTotalTimeout || timeCheck?.isQuestionTimeout; const isTimedOut = timeCheck?.isTotalTimeout || timeCheck?.isQuestionTimeout;
const messagesEndRef = useRef<HTMLDivElement>(null); const messagesEndRef = useRef<HTMLDivElement>(null);
@@ -106,6 +107,10 @@ export const AssessmentView: React.FC<AssessmentViewProps> = ({
setTimeCheck(data); setTimeCheck(data);
if (data.isTotalTimeout || data.isQuestionTimeout) { if (data.isTotalTimeout || data.isQuestionTimeout) {
setError(t('timeLimitExceeded')); setError(t('timeLimitExceeded'));
if (!autoSubmitted && !isLoading) {
setAutoSubmitted(true);
await handleSubmitAnswer(true);
}
} }
} catch (err) { } catch (err) {
console.error('Failed to check time:', err); console.error('Failed to check time:', err);
@@ -233,17 +238,19 @@ export const AssessmentView: React.FC<AssessmentViewProps> = ({
} }
}; };
const handleSubmitAnswer = async () => { const handleSubmitAnswer = async (forced = false) => {
const currentQuestion = state?.questions?.[state.currentQuestionIndex || 0] as any; const currentQuestion = state?.questions?.[state.currentQuestionIndex || 0] as any;
const isChoice = currentQuestion?.questionType === 'MULTIPLE_CHOICE' && currentQuestion?.options?.length > 0; const isChoice = currentQuestion?.questionType === 'MULTIPLE_CHOICE' && currentQuestion?.options?.length > 0;
if (isChoice) { if (!forced) {
if (!selectedChoice || isLoading || isTimedOut) return; if (isChoice) {
} else { if (!selectedChoice || isLoading || isTimedOut) return;
if (!inputValue.trim() || isLoading || isTimedOut) return; } else {
if (!inputValue.trim() || isLoading || isTimedOut) return;
}
} }
const answer = isChoice ? selectedChoice! : inputValue.trim(); const answer = isChoice ? (selectedChoice || '') : inputValue.trim();
setInputValue(''); setInputValue('');
setSelectedChoice(null); setSelectedChoice(null);
setIsLoading(true); setIsLoading(true);