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 updateExamMutation = useUpdateAdminExamMutation()
const addQuestionMutation = useAddAdminExamQuestionMutation() const addQuestionMutation = useAddAdminExamQuestionMutation()
const isSubmitting = ref(false)
const submitting = computed( const submitting = computed(
() => () =>
isSubmitting.value ||
addExamMutation.isPending.value || addExamMutation.isPending.value ||
updateExamMutation.isPending.value || updateExamMutation.isPending.value ||
addQuestionMutation.isPending.value addQuestionMutation.isPending.value
@@ -298,23 +301,29 @@ const postQuestionsSequentially = async (id, list) => {
} }
const onSubmit = async () => { const onSubmit = async () => {
const { isValid } = await validate(form.value) if (isSubmitting.value) return
const newQuestions = validateLocalQuestions() isSubmitting.value = true
if (!isValid || !newQuestions) return try {
const { isValid } = await validate(form.value)
const newQuestions = validateLocalQuestions()
if (!isValid || !newQuestions) return
const examPayload = buildExamPayload(form.value) const examPayload = buildExamPayload(form.value)
let targetExamId = examId.value let targetExamId = examId.value
if (isEditMode.value) { if (isEditMode.value) {
await updateExamMutation.mutateAsync({ id: targetExamId, payload: examPayload }) await updateExamMutation.mutateAsync({ id: targetExamId, payload: examPayload })
} else { } else {
const created = await addExamMutation.mutateAsync(examPayload) const created = await addExamMutation.mutateAsync(examPayload)
targetExamId = created?.data?.id ?? created?.id ?? targetExamId 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' }) const onCancel = () => router.push({ name: 'admin-exams' })