From 7b08b228df9da3df2916dde42ad7da81213ff666 Mon Sep 17 00:00:00 2001 From: Yared Yemane Date: Tue, 7 Apr 2026 03:44:41 -0700 Subject: [PATCH] refresh speaking practice filter after create Re-fetch practice options after creating a speaking practice and auto-select the new set so freshly created practices appear immediately in the filter and question list. Made-with: Cursor --- src/pages/content-management/SpeakingPage.tsx | 81 +++++++++---------- 1 file changed, 38 insertions(+), 43 deletions(-) diff --git a/src/pages/content-management/SpeakingPage.tsx b/src/pages/content-management/SpeakingPage.tsx index a99d353..ce50978 100644 --- a/src/pages/content-management/SpeakingPage.tsx +++ b/src/pages/content-management/SpeakingPage.tsx @@ -268,53 +268,46 @@ export function SpeakingPage() { fetchAudioQuestions() }, [fetchAudioQuestions, audioPageSize, selectedPracticeId]) - useEffect(() => { - let cancelled = false - const fetchPractices = async () => { - try { - const batchSize = 100 - let offset = 0 - let total = Number.POSITIVE_INFINITY - const all: QuestionSet[] = [] - while (all.length < total) { - const res = await getQuestionSets({ - set_type: "PRACTICE", - limit: batchSize, - offset, - }) - const payload = res.data?.data - let chunk: QuestionSet[] = [] - let chunkTotal = 0 - if (Array.isArray(payload)) { - chunk = payload - chunkTotal = payload.length - } else if (payload && typeof payload === "object") { - chunk = payload.question_sets ?? [] - chunkTotal = payload.total_count ?? chunk.length - } - all.push(...chunk) - total = chunkTotal - if (chunk.length < batchSize) break - offset += chunk.length - } - if (!cancelled) { - setPracticeOptions( - all.map((p) => ({ - id: p.id, - title: p.title, - })), - ) - } - } catch { - if (!cancelled) setPracticeOptions([]) + const fetchPracticeOptions = useCallback(async () => { + const batchSize = 100 + let offset = 0 + let total = Number.POSITIVE_INFINITY + const all: QuestionSet[] = [] + while (all.length < total) { + const res = await getQuestionSets({ + set_type: "PRACTICE", + limit: batchSize, + offset, + }) + const payload = res.data?.data + let chunk: QuestionSet[] = [] + let chunkTotal = 0 + if (Array.isArray(payload)) { + chunk = payload + chunkTotal = payload.length + } else if (payload && typeof payload === "object") { + chunk = payload.question_sets ?? [] + chunkTotal = payload.total_count ?? chunk.length } + all.push(...chunk) + total = chunkTotal + if (chunk.length < batchSize) break + offset += chunk.length } - fetchPractices() - return () => { - cancelled = true - } + setPracticeOptions( + all.map((p) => ({ + id: p.id, + title: p.title, + })), + ) }, []) + useEffect(() => { + fetchPracticeOptions().catch(() => { + setPracticeOptions([]) + }) + }, [fetchPracticeOptions]) + useEffect(() => { let cancelled = false const fetchSubCourseOptions = async () => { @@ -894,6 +887,8 @@ export function SpeakingPage() { setOpenCreate(false) setCurrentStep(1) resetCreateForm() + await fetchPracticeOptions() + setSelectedPracticeId(String(setId)) toast.success(`Speaking practice created with ${draftsToCreate.length} AUDIO question(s)`) await fetchAudioQuestions() } catch (error) {