On mobile, the single-column layout makes it easy to lose context when scrolling between the specializations and course selection panels. This adds two floating banners that appear via IntersectionObserver: - Top banner: summarizes specialization statuses (achieved/achievable/missing/unreachable) - Bottom banner: shows course selection progress (N/12 selected) Both slide in/out with CSS transitions and scroll to their respective sections on tap. Only rendered on mobile viewports (max-width: 639px).
24 lines
1.8 KiB
Markdown
24 lines
1.8 KiB
Markdown
## 1. Create MobileCourseBanner component
|
|
|
|
- [x] 1.1 Create `app/src/components/MobileCourseBanner.tsx` with props: `selectedCount: number`, `totalSets: number`, `visible: boolean`, `onTap: () => void`
|
|
- [x] 1.2 Render "{selectedCount} / {totalSets} courses selected" text
|
|
- [x] 1.3 Style the banner: `position: fixed`, `bottom: 0`, `left: 0`, `width: 100%`, `z-index: 1000`, white background with top border, compact height (~40px)
|
|
- [x] 1.4 Implement slide animation: always mounted, use `transform: translateY(100%)` when hidden vs `translateY(0)` when visible, `transition: transform 200ms ease-out`
|
|
- [x] 1.5 Attach `onClick` handler to the banner root element that calls `onTap`
|
|
|
|
## 2. Integrate into App.tsx
|
|
|
|
- [x] 2.1 Add a `courseSectionRef` to the course selection wrapper `<div>` in `App.tsx`
|
|
- [x] 2.2 Add a `courseBannerVisible` state and IntersectionObserver useEffect for the course section ref, gated on `isMobile`
|
|
- [x] 2.3 Mount `<MobileCourseBanner>` in the App return (after the existing `MobileStatusBanner`), passing `selectedCount={Object.keys(state.pinnedCourses).length}`, `totalSets={12}`, `visible={courseBannerVisible && isMobile}`, and `onTap` that calls `courseSectionRef.current.scrollIntoView({ behavior: 'smooth' })`
|
|
- [x] 2.4 Clean up the IntersectionObserver on unmount or when isMobile changes
|
|
|
|
## 3. Test
|
|
|
|
- [x] 3.1 Verify banner appears at bottom on mobile when scrolling above course selection
|
|
- [x] 3.2 Verify banner hides when scrolling back down to course selection
|
|
- [x] 3.3 Verify banner does not render on tablet/desktop
|
|
- [x] 3.4 Verify tapping the banner scrolls to the course selection section
|
|
- [x] 3.5 Verify selected count updates reactively when courses are pinned/unpinned
|
|
- [x] 3.6 Verify both top and bottom banners can coexist without visual conflict
|