fix(exams): prevent double-submit from creating duplicate exams
Deploy banu-front / deploy (push) Successful in 2m3s

The submit button only disabled after Vue re-rendered on mutation
pending state, leaving a window where a fast double-click fired
onSubmit twice — creating two exam rows, with the losing request
usually failing to attach its questions (an "empty" duplicate exam).
This commit is contained in:
madresebanoo
2026-09-20 16:35:36 +04:30
parent a967479c9f
commit 6c4bc4e575
+24 -15
View File
@@ -283,8 +283,11 @@ const addExamMutation = useAddAdminExamMutation()
const updateExamMutation = useUpdateAdminExamMutation()
const addQuestionMutation = useAddAdminExamQuestionMutation()
const isSubmitting = ref(false)
const submitting = computed(
() =>
isSubmitting.value ||
addExamMutation.isPending.value ||
updateExamMutation.isPending.value ||
addQuestionMutation.isPending.value
@@ -298,23 +301,29 @@ const postQuestionsSequentially = async (id, list) => {
}
const onSubmit = async () => {
const { isValid } = await validate(form.value)
const newQuestions = validateLocalQuestions()
if (!isValid || !newQuestions) return
if (isSubmitting.value) return
isSubmitting.value = true
try {
const { isValid } = await validate(form.value)
const newQuestions = validateLocalQuestions()
if (!isValid || !newQuestions) return
const examPayload = buildExamPayload(form.value)
let targetExamId = examId.value
if (isEditMode.value) {
await updateExamMutation.mutateAsync({ id: targetExamId, payload: examPayload })
} else {
const created = await addExamMutation.mutateAsync(examPayload)
targetExamId = created?.data?.id ?? created?.id ?? targetExamId
const examPayload = buildExamPayload(form.value)
let targetExamId = examId.value
if (isEditMode.value) {
await updateExamMutation.mutateAsync({ id: targetExamId, payload: examPayload })
} else {
const created = await addExamMutation.mutateAsync(examPayload)
targetExamId = created?.data?.id ?? created?.id ?? targetExamId
}
if (targetExamId && newQuestions.length > 0) {
await postQuestionsSequentially(targetExamId, newQuestions)
}
await queryClient.invalidateQueries({ queryKey: adminExamsKeys.all, refetchType: 'all' })
router.push({ name: 'admin-exams' })
} finally {
isSubmitting.value = false
}
if (targetExamId && newQuestions.length > 0) {
await postQuestionsSequentially(targetExamId, newQuestions)
}
await queryClient.invalidateQueries({ queryKey: adminExamsKeys.all, refetchType: 'all' })
router.push({ name: 'admin-exams' })
}
const onCancel = () => router.push({ name: 'admin-exams' })