feat(mobile): Implement responsive mobile menu with band context preservation
This commit implements a comprehensive mobile menu solution that: 1. **Mobile Menu Components**: - Created TopBar.tsx with circular band switcher (mobile only) - Enhanced BottomNavBar.tsx with band-context-aware navigation - Updated ResponsiveLayout.tsx to integrate TopBar for mobile views 2. **Band Context Preservation**: - Fixed black screen issue by preserving band context via React Router state - Implemented dual context detection (URL params + location state) - Added graceful fallback handling for missing context 3. **Visual Improvements**: - Changed band display from square+text to perfect circle with initials only - Updated dropdown items to use consistent circular format - Improved mobile space utilization 4. **Debugging & Testing**: - Added comprehensive debug logging for issue tracking - Created test plans and documentation - Ensured all static checks pass (TypeScript + ESLint) 5. **Shared Utilities**: - Created utils.ts with shared getInitials() function - Reduced code duplication across components Key Features: - Mobile (<768px): TopBar + BottomNavBar + Main Content - Desktop (≥768px): Sidebar (unchanged) - Band context preserved across all mobile navigation - Graceful error handling and fallbacks - Comprehensive debug logging (can be removed in production) Files Changed: - web/src/utils.ts (new) - web/src/components/TopBar.tsx (new) - web/src/components/BottomNavBar.tsx (modified) - web/src/components/ResponsiveLayout.tsx (modified) - web/src/components/Sidebar.tsx (modified) Documentation Added: - implementation_summary.md - refinement_summary.md - black_screen_fix_summary.md - test_plan_mobile_menu_fix.md - test_plan_refinement.md - testing_guide.md - black_screen_debug.md Resolves: - Mobile menu band context loss - Black screen on Library navigation - Inconsistent band display format - Missing mobile band switching capability Breaking Changes: None Backward Compatibility: Fully maintained Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
@@ -79,10 +79,17 @@ function NavItem({ icon, label, active, onClick, disabled }: NavItemProps) {
|
||||
export function BottomNavBar() {
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
|
||||
// Derive current band from URL
|
||||
const bandMatch = matchPath("/bands/:bandId/*", location.pathname) ?? matchPath("/bands/:bandId", location.pathname);
|
||||
const currentBandId = bandMatch?.params?.bandId || location.state?.fromBandId;
|
||||
|
||||
// Debug logging for black screen issue
|
||||
console.log("BottomNavBar - Current band ID:", currentBandId, "Path:", location.pathname, "State:", location.state);
|
||||
|
||||
// Derive active states
|
||||
const isLibrary = !!matchPath("/bands/:bandId", location.pathname);
|
||||
const isLibrary = !!matchPath("/bands/:bandId", location.pathname) ||
|
||||
!!matchPath("/bands/:bandId/sessions/:sessionId", location.pathname);
|
||||
const isPlayer = !!matchPath("/bands/:bandId/songs/:songId", location.pathname);
|
||||
const isSettings = location.pathname.startsWith("/settings");
|
||||
|
||||
@@ -104,26 +111,34 @@ export function BottomNavBar() {
|
||||
icon={<IconLibrary />}
|
||||
label="Library"
|
||||
active={isLibrary}
|
||||
onClick={() => navigate("/bands")}
|
||||
onClick={() => {
|
||||
console.log("Library click - Navigating to band:", currentBandId);
|
||||
if (currentBandId) {
|
||||
navigate(`/bands/${currentBandId}`);
|
||||
} else {
|
||||
console.warn("Library click - No current band ID found!");
|
||||
navigate("/bands");
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<NavItem
|
||||
icon={<IconPlay />}
|
||||
label="Player"
|
||||
active={isPlayer}
|
||||
onClick={() => {}}
|
||||
disabled={!isPlayer}
|
||||
onClick={() => currentBandId ? navigate(`/bands/${currentBandId}/songs`) : {}}
|
||||
disabled={!currentBandId}
|
||||
/>
|
||||
<NavItem
|
||||
icon={<IconMembers />}
|
||||
label="Members"
|
||||
active={false}
|
||||
onClick={() => navigate("/settings")}
|
||||
onClick={() => currentBandId ? navigate(`/bands/${currentBandId}/settings/members`) : navigate("/settings", { state: { fromBandId: currentBandId } })}
|
||||
/>
|
||||
<NavItem
|
||||
icon={<IconSettings />}
|
||||
label="Settings"
|
||||
active={isSettings}
|
||||
onClick={() => navigate("/settings")}
|
||||
onClick={() => currentBandId ? navigate("/settings", { state: { fromBandId: currentBandId } }) : navigate("/settings")}
|
||||
/>
|
||||
</nav>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user