fix category and course loading with duplicate names
Normalize duplicate category names in hierarchy responses and aggregate courses across same-name category IDs so Human Language and Courses tabs consistently show data. Made-with: Cursor
This commit is contained in:
parent
da6754e6f5
commit
78111f161f
|
|
@ -81,7 +81,10 @@ type CourseHierarchyRow = {
|
||||||
export const getCourseCategories = () =>
|
export const getCourseCategories = () =>
|
||||||
http.get("/course-management/hierarchy").then((res) => {
|
http.get("/course-management/hierarchy").then((res) => {
|
||||||
const rows: UnifiedHierarchyRow[] = res.data?.data ?? []
|
const rows: UnifiedHierarchyRow[] = res.data?.data ?? []
|
||||||
const categoriesMap = new Map<number, { id: number; name: string; is_active: boolean; created_at: string }>()
|
const categoriesMap = new Map<
|
||||||
|
number,
|
||||||
|
{ id: number; name: string; is_active: boolean; created_at: string; subCategoryCount: number; courseCount: number }
|
||||||
|
>()
|
||||||
rows.forEach((r) => {
|
rows.forEach((r) => {
|
||||||
if (!categoriesMap.has(r.category_id)) {
|
if (!categoriesMap.has(r.category_id)) {
|
||||||
categoriesMap.set(r.category_id, {
|
categoriesMap.set(r.category_id, {
|
||||||
|
|
@ -89,10 +92,50 @@ export const getCourseCategories = () =>
|
||||||
name: r.category_name,
|
name: r.category_name,
|
||||||
is_active: true,
|
is_active: true,
|
||||||
created_at: new Date().toISOString(),
|
created_at: new Date().toISOString(),
|
||||||
|
subCategoryCount: 0,
|
||||||
|
courseCount: 0,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
const category = categoriesMap.get(r.category_id)!
|
||||||
|
if (r.sub_category_id) category.subCategoryCount += 1
|
||||||
|
if (r.course_id) category.courseCount += 1
|
||||||
})
|
})
|
||||||
const categories = Array.from(categoriesMap.values())
|
|
||||||
|
// Merge duplicate top-level category names by selecting the richest representative.
|
||||||
|
type CategoryAggregate = {
|
||||||
|
id: number
|
||||||
|
name: string
|
||||||
|
is_active: boolean
|
||||||
|
created_at: string
|
||||||
|
subCategoryCount: number
|
||||||
|
courseCount: number
|
||||||
|
}
|
||||||
|
const categoryByName = new Map<string, CategoryAggregate>()
|
||||||
|
Array.from(categoriesMap.values()).forEach((category) => {
|
||||||
|
const key = category.name.trim().toLowerCase()
|
||||||
|
const existing = categoryByName.get(key)
|
||||||
|
if (!existing) {
|
||||||
|
categoryByName.set(key, category)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (category.subCategoryCount > existing.subCategoryCount) {
|
||||||
|
categoryByName.set(key, category)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (category.subCategoryCount === existing.subCategoryCount && category.courseCount > existing.courseCount) {
|
||||||
|
categoryByName.set(key, category)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
category.subCategoryCount === existing.subCategoryCount &&
|
||||||
|
category.courseCount === existing.courseCount &&
|
||||||
|
category.id > existing.id
|
||||||
|
) {
|
||||||
|
categoryByName.set(key, category)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const categories = Array.from(categoryByName.values()).map(({ subCategoryCount, courseCount, ...category }) => category)
|
||||||
return {
|
return {
|
||||||
...res,
|
...res,
|
||||||
data: {
|
data: {
|
||||||
|
|
@ -113,17 +156,32 @@ export const createCourseCategory = (data: CreateCourseCategoryRequest) =>
|
||||||
export const getCoursesByCategory = (categoryId: number) =>
|
export const getCoursesByCategory = (categoryId: number) =>
|
||||||
http.get("/course-management/hierarchy").then((res) => {
|
http.get("/course-management/hierarchy").then((res) => {
|
||||||
const rows: UnifiedHierarchyRow[] = res.data?.data ?? []
|
const rows: UnifiedHierarchyRow[] = res.data?.data ?? []
|
||||||
const courses = rows
|
|
||||||
.filter((r) => r.category_id === categoryId && r.course_id)
|
const requestedCategoryRows = rows.filter((r) => r.category_id === categoryId)
|
||||||
.map((r) => ({
|
const requestedCategoryName = requestedCategoryRows.find((r) => !!r.category_name)?.category_name?.trim().toLowerCase()
|
||||||
id: Number(r.course_id),
|
const relevantRows = requestedCategoryName
|
||||||
category_id: r.category_id,
|
? rows.filter((r) => r.category_name?.trim().toLowerCase() === requestedCategoryName)
|
||||||
sub_category_id: r.sub_category_id ?? null,
|
: requestedCategoryRows
|
||||||
title: r.course_title ?? "",
|
|
||||||
description: "",
|
const courseMap = new Map<number, { id: number; category_id: number; sub_category_id: number | null; title: string; description: string; thumbnail: string; is_active: boolean }>()
|
||||||
thumbnail: "",
|
relevantRows
|
||||||
is_active: true,
|
.filter((r) => r.course_id)
|
||||||
}))
|
.forEach((r) => {
|
||||||
|
const id = Number(r.course_id)
|
||||||
|
if (!Number.isFinite(id)) return
|
||||||
|
if (courseMap.has(id)) return
|
||||||
|
courseMap.set(id, {
|
||||||
|
id,
|
||||||
|
category_id: r.category_id,
|
||||||
|
sub_category_id: r.sub_category_id ?? null,
|
||||||
|
title: r.course_title ?? "",
|
||||||
|
description: "",
|
||||||
|
thumbnail: "",
|
||||||
|
is_active: true,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
const courses = Array.from(courseMap.values())
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...res,
|
...res,
|
||||||
data: { ...res.data, data: { courses, total_count: courses.length } },
|
data: { ...res.data, data: { courses, total_count: courses.length } },
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user