Fix Human Language level actions visibility and CEFR add-level guidance.
Avoid nested button markup so remove-level controls render reliably, keep level rows visible for all CEFR levels, and add clearer guidance/labeling for incremental level creation starting from A1. Made-with: Cursor
This commit is contained in:
parent
bf0dabbf05
commit
767637a5ef
|
|
@ -313,14 +313,22 @@ export function HumanLanguagePage() {
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
<CardContent className="pt-0">
|
<CardContent className="border-t border-grayScale-100 pt-4">
|
||||||
<div className="flex items-center justify-end">
|
<div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
|
||||||
|
<p className="text-xs text-grayScale-500">
|
||||||
|
{selectedCourseId === "ALL"
|
||||||
|
? "Select a specific course above to enable adding the next CEFR level (starts at A1) and to use remove actions."
|
||||||
|
: levelsForSelectedCourse.length >= CEFR_LEVELS.length
|
||||||
|
? "All CEFR levels (A1–C3) already have content for this course."
|
||||||
|
: `Next level to add: ${CEFR_LEVELS.find((l) => !levelsForSelectedCourse.includes(l)) ?? "—"}`}
|
||||||
|
</p>
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
|
className="shrink-0"
|
||||||
onClick={handleCreateNextLevel}
|
onClick={handleCreateNextLevel}
|
||||||
disabled={selectedCourseId === "ALL" || levelsForSelectedCourse.length >= CEFR_LEVELS.length || creatingKey?.startsWith("next-level-")}
|
disabled={selectedCourseId === "ALL" || levelsForSelectedCourse.length >= CEFR_LEVELS.length || creatingKey?.startsWith("next-level-")}
|
||||||
>
|
>
|
||||||
{creatingKey?.startsWith("next-level-") ? "Creating level..." : "Add Next Level"}
|
{creatingKey?.startsWith("next-level-") ? "Creating level..." : "Add next CEFR level"}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
|
|
@ -388,46 +396,43 @@ export function HumanLanguagePage() {
|
||||||
|
|
||||||
{availableCourses.length > 0
|
{availableCourses.length > 0
|
||||||
? CEFR_LEVELS.filter((l) => selectedLevel === "ALL" || l === selectedLevel).map((level) => {
|
? CEFR_LEVELS.filter((l) => selectedLevel === "ALL" || l === selectedLevel).map((level) => {
|
||||||
const modulesByCourse = selectedCourses
|
const modulesByCourse = selectedCourses.map((course: HumanLanguageCourseTree) => {
|
||||||
.map((course: HumanLanguageCourseTree) => {
|
const levelNode = course.levels.find((item) => item.level.toUpperCase() === level)
|
||||||
const levelNode = course.levels.find((item) => item.level.toUpperCase() === level)
|
return {
|
||||||
return {
|
course,
|
||||||
course,
|
modules: levelNode?.modules ?? [],
|
||||||
modules: levelNode?.modules ?? [],
|
}
|
||||||
}
|
})
|
||||||
})
|
|
||||||
.filter((entry) => entry.modules.length > 0 || (selectedCourses.length > 0 && level === "A1"))
|
|
||||||
return (
|
return (
|
||||||
<Card key={level} className="overflow-hidden border-grayScale-200/80 shadow-sm">
|
<Card key={level} className="overflow-hidden border-grayScale-200/80 shadow-sm">
|
||||||
<button
|
<div className="flex w-full flex-wrap items-center justify-between gap-2 border-b border-grayScale-100 bg-grayScale-50/60 px-4 py-3">
|
||||||
type="button"
|
<button
|
||||||
className="flex w-full items-center justify-between border-b border-grayScale-100 bg-grayScale-50/60 px-4 py-3 text-left"
|
type="button"
|
||||||
onClick={() => toggleLevel(level)}
|
className="flex min-w-0 flex-1 items-center gap-2 text-left"
|
||||||
>
|
onClick={() => toggleLevel(level)}
|
||||||
<div className="inline-flex items-center gap-2">
|
>
|
||||||
{collapsedLevels.includes(level) ? <ChevronRight className="h-4 w-4" /> : <ChevronDown className="h-4 w-4" />}
|
{collapsedLevels.includes(level) ? <ChevronRight className="h-4 w-4 shrink-0" /> : <ChevronDown className="h-4 w-4 shrink-0" />}
|
||||||
<span className="text-sm font-semibold text-grayScale-900">{level}</span>
|
<span className="text-sm font-semibold text-grayScale-900">{level}</span>
|
||||||
<span className="rounded-md bg-brand-100 px-2 py-0.5 text-xs font-medium text-brand-700">
|
<span className="rounded-md bg-brand-100 px-2 py-0.5 text-xs font-medium text-brand-700">
|
||||||
{modulesByCourse.reduce((sum, entry) => sum + entry.modules.length, 0)} module(s)
|
{modulesByCourse.reduce((sum, entry) => sum + entry.modules.length, 0)} module(s)
|
||||||
</span>
|
</span>
|
||||||
<Button
|
</button>
|
||||||
size="sm"
|
<Button
|
||||||
variant="outline"
|
size="sm"
|
||||||
className="ml-3 border-red-200 text-red-600 hover:bg-red-50"
|
variant="outline"
|
||||||
disabled={selectedCourseId === "ALL" || deletingKey === `level-${selectedCourseId}-${level}`}
|
className="border-red-200 text-red-600 hover:bg-red-50"
|
||||||
onClick={(e) => {
|
disabled={selectedCourseId === "ALL" || deletingKey === `level-${selectedCourseId}-${level}`}
|
||||||
e.stopPropagation()
|
onClick={() => {
|
||||||
if (selectedCourseId === "ALL") return
|
if (selectedCourseId === "ALL") return
|
||||||
const courseEntry = modulesByCourse.find((entry) => entry.course.course_id === selectedCourseId)
|
const courseEntry = modulesByCourse.find((entry) => entry.course.course_id === selectedCourseId)
|
||||||
const ids = (courseEntry?.modules ?? []).flatMap((m) => m.sub_modules.map((s) => s.id))
|
const ids = (courseEntry?.modules ?? []).flatMap((m) => m.sub_modules.map((s) => s.id))
|
||||||
handleDeleteSubModules(ids, `level-${selectedCourseId}-${level}`, `Level ${level} removed`)
|
handleDeleteSubModules(ids, `level-${selectedCourseId}-${level}`, `Level ${level} removed`)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Trash2 className="h-3.5 w-3.5" />
|
<Trash2 className="h-3.5 w-3.5" />
|
||||||
Remove Level
|
Remove level
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
|
||||||
{!collapsedLevels.includes(level) ? (
|
{!collapsedLevels.includes(level) ? (
|
||||||
<CardContent className="space-y-3 p-4">
|
<CardContent className="space-y-3 p-4">
|
||||||
{modulesByCourse.length === 0 ? (
|
{modulesByCourse.length === 0 ? (
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user