Add lesson detail fallback for new lessons
Handle environments where sub-module lesson detail is missing by falling back to question-set detail, and keep lesson form/status typing safe. Made-with: Cursor
This commit is contained in:
parent
3ad0f0a63d
commit
5ee897cfad
|
|
@ -929,7 +929,7 @@ export function HumanLanguagePage() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadLessonDetailIfNeeded = async (lessonId: number, forceRefresh = false) => {
|
const loadLessonDetailIfNeeded = async (lessonId: number, lessonQuestionSetId?: number, forceRefresh = false) => {
|
||||||
let skipFetch = false
|
let skipFetch = false
|
||||||
setLessonDetailState((prev) => {
|
setLessonDetailState((prev) => {
|
||||||
const ex = prev[lessonId]
|
const ex = prev[lessonId]
|
||||||
|
|
@ -953,6 +953,38 @@ export function HumanLanguagePage() {
|
||||||
[lessonId]: { status: "ok", data },
|
[lessonId]: { status: "ok", data },
|
||||||
}))
|
}))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
// Fallback: some environments return lessons via question-set data,
|
||||||
|
// and /sub-module-lessons/:id may not have a corresponding row yet.
|
||||||
|
if (lessonQuestionSetId && lessonQuestionSetId > 0) {
|
||||||
|
try {
|
||||||
|
const setDetail = (await withTimeout(getQuestionSetById(lessonQuestionSetId), 12000)).data?.data
|
||||||
|
if (setDetail) {
|
||||||
|
setLessonDetailState((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[lessonId]: {
|
||||||
|
status: "ok",
|
||||||
|
data: {
|
||||||
|
id: lessonId,
|
||||||
|
sub_module_id: 0,
|
||||||
|
question_set_id: lessonQuestionSetId,
|
||||||
|
intro_video_url: setDetail.intro_video_url ?? null,
|
||||||
|
display_order: 0,
|
||||||
|
is_active: true,
|
||||||
|
title: setDetail.title ?? "",
|
||||||
|
description: setDetail.description ?? "",
|
||||||
|
status: setDetail.status ?? "DRAFT",
|
||||||
|
set_type: setDetail.set_type ?? "QUIZ",
|
||||||
|
question_count: Number(setDetail.question_count ?? 0),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} catch (fallbackError) {
|
||||||
|
console.error("Fallback question-set detail failed:", fallbackError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
console.error("Failed to load lesson detail:", error)
|
console.error("Failed to load lesson detail:", error)
|
||||||
setLessonDetailState((prev) => ({
|
setLessonDetailState((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
|
|
@ -1033,18 +1065,38 @@ export function HumanLanguagePage() {
|
||||||
})
|
})
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const detail = (await getSubModuleLessonById(lesson.id, { cacheBust: true })).data?.data
|
let detail: SubModuleLessonDetail | null =
|
||||||
|
(await getSubModuleLessonById(lesson.id, { cacheBust: true })).data?.data ?? null
|
||||||
|
if (!detail && lesson.question_set_id > 0) {
|
||||||
|
const setDetail = (await getQuestionSetById(lesson.question_set_id)).data?.data
|
||||||
|
detail = setDetail
|
||||||
|
? ({
|
||||||
|
id: lesson.id,
|
||||||
|
sub_module_id: 0,
|
||||||
|
question_set_id: lesson.question_set_id,
|
||||||
|
intro_video_url: setDetail.intro_video_url ?? null,
|
||||||
|
display_order: 0,
|
||||||
|
is_active: true,
|
||||||
|
title: setDetail.title ?? "",
|
||||||
|
description: setDetail.description ?? "",
|
||||||
|
status: setDetail.status ?? "DRAFT",
|
||||||
|
set_type: setDetail.set_type ?? "QUIZ",
|
||||||
|
question_count: Number(setDetail.question_count ?? 0),
|
||||||
|
} as SubModuleLessonDetail)
|
||||||
|
: null
|
||||||
|
}
|
||||||
if (lessonEditFetchIdRef.current !== requestId) return
|
if (lessonEditFetchIdRef.current !== requestId) return
|
||||||
|
|
||||||
|
const normalizedStatus =
|
||||||
|
detail?.status && ["DRAFT", "PUBLISHED", "ARCHIVED"].includes(detail.status)
|
||||||
|
? (detail.status as "DRAFT" | "PUBLISHED" | "ARCHIVED")
|
||||||
|
: "DRAFT"
|
||||||
|
|
||||||
setLessonForm({
|
setLessonForm({
|
||||||
title: detail?.title ?? lesson.title ?? "",
|
title: detail?.title ?? lesson.title ?? "",
|
||||||
description: detail?.description ?? "",
|
description: detail?.description ?? "",
|
||||||
introVideoUrl: detail?.intro_video_url ?? "",
|
introVideoUrl: detail?.intro_video_url ?? "",
|
||||||
status:
|
status: normalizedStatus,
|
||||||
(detail?.status as "DRAFT" | "PUBLISHED" | "ARCHIVED" | undefined) &&
|
|
||||||
["DRAFT", "PUBLISHED", "ARCHIVED"].includes(detail.status)
|
|
||||||
? (detail.status as "DRAFT" | "PUBLISHED" | "ARCHIVED")
|
|
||||||
: "DRAFT",
|
|
||||||
})
|
})
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (lessonEditFetchIdRef.current !== requestId) return
|
if (lessonEditFetchIdRef.current !== requestId) return
|
||||||
|
|
@ -1441,7 +1493,7 @@ export function HumanLanguagePage() {
|
||||||
const cur = prev[smKey] ?? { lessonId: null, practiceId: null }
|
const cur = prev[smKey] ?? { lessonId: null, practiceId: null }
|
||||||
return { ...prev, [smKey]: { ...cur, lessonId: nextLessonId } }
|
return { ...prev, [smKey]: { ...cur, lessonId: nextLessonId } }
|
||||||
})
|
})
|
||||||
if (nextLessonId !== null) void loadLessonDetailIfNeeded(nextLessonId)
|
if (nextLessonId !== null) void loadLessonDetailIfNeeded(nextLessonId, lessonQuestionSetId)
|
||||||
if (nextLessonId !== null && lessonQuestionSetId > 0) void loadLessonQuestionsIfNeeded(lessonQuestionSetId)
|
if (nextLessonId !== null && lessonQuestionSetId > 0) void loadLessonQuestionsIfNeeded(lessonQuestionSetId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user