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).
1.8 KiB
1.8 KiB
1. Create MobileCourseBanner component
- 1.1 Create
app/src/components/MobileCourseBanner.tsxwith props:selectedCount: number,totalSets: number,visible: boolean,onTap: () => void - 1.2 Render "{selectedCount} / {totalSets} courses selected" text
- 1.3 Style the banner:
position: fixed,bottom: 0,left: 0,width: 100%,z-index: 1000, white background with top border, compact height (~40px) - 1.4 Implement slide animation: always mounted, use
transform: translateY(100%)when hidden vstranslateY(0)when visible,transition: transform 200ms ease-out - 1.5 Attach
onClickhandler to the banner root element that callsonTap
2. Integrate into App.tsx
- 2.1 Add a
courseSectionRefto the course selection wrapper<div>inApp.tsx - 2.2 Add a
courseBannerVisiblestate and IntersectionObserver useEffect for the course section ref, gated onisMobile - 2.3 Mount
<MobileCourseBanner>in the App return (after the existingMobileStatusBanner), passingselectedCount={Object.keys(state.pinnedCourses).length},totalSets={12},visible={courseBannerVisible && isMobile}, andonTapthat callscourseSectionRef.current.scrollIntoView({ behavior: 'smooth' }) - 2.4 Clean up the IntersectionObserver on unmount or when isMobile changes
3. Test
- 3.1 Verify banner appears at bottom on mobile when scrolling above course selection
- 3.2 Verify banner hides when scrolling back down to course selection
- 3.3 Verify banner does not render on tablet/desktop
- 3.4 Verify tapping the banner scrolls to the course selection section
- 3.5 Verify selected count updates reactively when courses are pinned/unpinned
- 3.6 Verify both top and bottom banners can coexist without visual conflict