Эх сурвалжийг харах

fix(mobile): collapse student learning content after three items

彭峰 1 долоо хоног өмнө
parent
commit
0b617aa4a9

+ 4 - 1
projects/xiaoshu-mobile/src/app/features/course-center/course-center-page.component.html

@@ -6,7 +6,10 @@
       <section class="course-band">
         <header><lucide-icon [img]="icons.BookOpen" [size]="21" /><h2>我的学习内容</h2><span>{{ (loading()||error())&&!courses().length ? '—' : courses().length }} 项</span></header>
         @if (courses().length) {
-          <ul class="course-list">@for (item of courses(); track courseBindingId(item) || courseId(item) || $index) { <li><button type="button" [class.readonly]="!canStartPointReading" [disabled]="!canOpenCourse(item)" (click)="openCourse(item)"><span><strong>{{ courseCategory(item) ? courseCategory(item)+' · ' : '' }}{{ courseTitle(item) }}</strong><small>{{ courseHint(item) }}</small></span><lucide-icon [img]="icons.ChevronRight" [size]="18" /></button></li> }</ul>
+          <ul class="course-list" id="learning-course-list">@for (item of visibleCourses(); track courseBindingId(item) || courseId(item) || $index) { <li><button type="button" [class.readonly]="!canStartPointReading" [disabled]="!canOpenCourse(item)" (click)="openCourse(item)"><span><strong>{{ courseCategory(item) ? courseCategory(item)+' · ' : '' }}{{ courseTitle(item) }}</strong><small>{{ courseHint(item) }}</small></span><lucide-icon [img]="icons.ChevronRight" [size]="18" /></button></li> }</ul>
+          @if (courses().length > 3) {
+            <button class="course-toggle" type="button" (click)="toggleCourses()" [attr.aria-expanded]="coursesExpanded()" aria-controls="learning-course-list"><span>{{ coursesExpanded() ? '收起' : '展开其余 ' + (courses().length - 3) + ' 项' }}</span><lucide-icon [img]="icons.ChevronDown" [size]="18" [class.expanded]="coursesExpanded()" /></button>
+          }
         } @else { <p class="band-empty">{{ error() ? '学习内容暂时无法加载,请重试' : loading() ? '正在读取学习内容…' : '暂未分配学习内容,请联系老师' }}</p> }
       </section>
     }

+ 2 - 0
projects/xiaoshu-mobile/src/app/features/course-center/course-center-page.component.scss

@@ -6,6 +6,8 @@ header h2 { margin: 0; color: var(--ink); font-size: 17px; letter-spacing: 0; }
 header span { color: var(--ink-soft); font-size: 12px; }
 .course-band > header h2, .schedule-band > header h2 { color: white; }
 .course-band > header span, .schedule-band > header span { color: rgb(255 255 255 / 78%); }
+.course-toggle { display: flex; width: 100%; min-height: 44px; align-items: center; justify-content: center; gap: 6px; padding: 8px 16px; color: var(--brand-deep); background: var(--brand-wash); border: 0; border-top: 1px solid var(--line); font: inherit; font-size: 12px; cursor: pointer; }
+.course-toggle lucide-icon.expanded { transform: rotate(180deg); }
 .course-list { margin: 0; padding: 0; list-style: none; }
 .course-list li { border-bottom: 1px solid var(--line); }
 .course-list li:last-child { border-bottom: 0; }

+ 5 - 2
projects/xiaoshu-mobile/src/app/features/course-center/course-center-page.component.ts

@@ -4,7 +4,7 @@ import { CommonModule } from '@angular/common';
 import { ChangeDetectionStrategy, Component, computed, inject, NgZone, OnDestroy, OnInit, signal } from '@angular/core';
 import { FormsModule } from '@angular/forms';
 import { ActivatedRoute, Router } from '@angular/router';
-import { AlertCircle, BarChart3, BookOpen, CalendarDays, ChevronRight, GraduationCap, LoaderCircle, LucideAngularModule, Search, X } from 'lucide-angular';
+import { AlertCircle, BarChart3, BookOpen, CalendarDays, ChevronDown, ChevronRight, GraduationCap, LoaderCircle, LucideAngularModule, Search, X } from 'lucide-angular';
 import { finalize, map, Subscription } from 'rxjs';
 import { HomeDailyCacheService } from '../../core/home-daily-cache.service';
 import { ApiError, ApiService } from '../../core/api.service';
@@ -69,6 +69,9 @@ export class CourseCenterPageComponent implements OnInit, OnDestroy {
   readonly listPage=signal(1); readonly listPages=signal(1); readonly listTotal=signal(0); readonly serverDates=signal<Array<{date:string;finished:number;planned:number}>>([]); readonly serverStudents=signal<StudentOption[]>([]);
   private loadRequest?:Subscription; private loadId=0;
   readonly courses = signal<Item[]>([]);
+  readonly coursesExpanded = signal(false);
+  readonly visibleCourses = computed(() => this.coursesExpanded() ? this.courses() : this.courses().slice(0, 3));
+  toggleCourses(): void { this.coursesExpanded.update(expanded => !expanded); }
   readonly schedules = signal<Item[]>([]);
   readonly scheduleFilter = signal<ScheduleFilter>('all');
   readonly scheduleRange = signal<ScheduleRange>('day');
@@ -100,7 +103,7 @@ export class CourseCenterPageComponent implements OnInit, OnDestroy {
     if (this.scheduleRange() === 'week') return `${this.selectedDate()} 所在周`;
     return this.selectedDate();
   });
-  readonly icons = { AlertCircle, BarChart3, BookOpen, CalendarDays, ChevronRight, GraduationCap, LoaderCircle, Search, X };
+  readonly icons = { AlertCircle, BarChart3, BookOpen, CalendarDays, ChevronDown, ChevronRight, GraduationCap, LoaderCircle, Search, X };
 
   private readonly api = inject(ApiService);
   private readonly dailyCache = inject(HomeDailyCacheService);