src/components/layout/mobile-bottom-nav.tsx- Mobile bottom navigation barsrc/components/layout/full-screen-overlay.tsx- Full-screen mobile overlay with cancel buttonsrc/components/layout/topbar.tsx- Updated with enhanced dropdown (mobile menu items)
Add to src/components/layout/main-layout.tsx:
import { MobileBottomNav } from './mobile-bottom-nav';
import { FullScreenOverlay } from './full-screen-overlay';After existing state declarations:
const [mobileTab, setMobileTab] = useState<'chats' | 'contacts' | 'wallet' | 'settings' | 'more'>('chats');Change the left sidebar div from:
<div className={`${currentUser && selectedConversation ? 'hidden md:flex' : 'flex'} w-full md:w-80 ...`}>To:
<div className="hidden md:flex w-80 bg-gradient-to-b from-black via-gray-900 to-black border-r border-violet-900/20 flex-col">Change from:
<div className={`${currentUser && !selectedConversation ? 'hidden md:flex' : 'flex'} flex-1 flex-col ...`}>To:
<div className="flex-1 flex flex-col bg-gradient-to-br from-gray-950 via-black to-gray-950 pb-16 md:pb-0">Before closing the main div, add:
{currentUser && (
<MobileBottomNav
activeTab={mobileTab}
onTabChange={setMobileTab}
unreadCount={0}
onOpenProfile={() => {}}
onOpenSecurity={() => {}}
onOpenStats={() => {}}
onOpenNewChat={() => setShowNewChat(true)}
onOpenNewContact={() => {}}
/>
)}Add logic to show/hide content based on mobileTab:
{/* Mobile: Conditional rendering */}
<div className="md:hidden h-full">
{mobileTab === 'chats' && (
// Show chat interface or conversation list
)}
{mobileTab === 'wallet' && (
<FullScreenOverlay isOpen={true} onClose={() => setMobileTab('chats')} title="Wallet">
{/* Wallet content */}
</FullScreenOverlay>
)}
{mobileTab === 'settings' && (
<FullScreenOverlay isOpen={true} onClose={() => setMobileTab('chats')} title="Settings">
<SettingsOverlay onClose={() => setMobileTab('chats')} />
</FullScreenOverlay>
)}
</div>
{/* Desktop: Existing layout */}
<div className="hidden md:block">
{/* Current chat interface code */}
</div>| Class | Purpose |
|---|---|
md:hidden |
Hide on desktop (≥768px), show on mobile |
hidden md:flex |
Hide on mobile, show on desktop |
pb-16 md:pb-0 |
Padding bottom for mobile nav, none on desktop |
fixed bottom-0 |
Fixed bottom positioning |
Bottom Nav Bar (Mobile Only)
├── Chats (with unread badge)
├── Contacts
├── Wallet
├── Settings
└── More (dropdown)
├── My Profile
├── Security Status
├── Activity Stats
├── New Chat
└── Add Contact
Left Sidebar
├── User profile card
├── Wallet balance
├── Quick actions
├── Security status
└── Conversation list
Top Bar
├── Logo
├── Search (center)
└── User dropdown
Here's the absolute minimum to get mobile navigation working:
export function MainLayout({ currentUser, onLogin, onLogout }: MainLayoutProps) {
const [mobileTab, setMobileTab] = useState<'chats' | 'contacts' | 'wallet' | 'settings' | 'more'>('chats');
// ... existing state ...
return (
<div className="h-screen bg-black text-white flex flex-col">
<Topbar {...props} />
<div className="flex-1 flex overflow-hidden">
{/* Desktop Sidebar - hidden on mobile */}
<div className="hidden md:flex w-80">
{/* Existing sidebar content */}
</div>
{/* Main Area - responsive */}
<div className="flex-1 pb-16 md:pb-0">
{/* Your chat interface */}
</div>
</div>
{/* Mobile Bottom Nav - only on mobile */}
{currentUser && (
<MobileBottomNav
activeTab={mobileTab}
onTabChange={setMobileTab}
onOpenNewChat={() => setShowNewChat(true)}
{...otherProps}
/>
)}
</div>
);
}# Build to verify no errors
npm run build
# Run dev server
npm run dev
# Test in browser dev tools:
# - Toggle device toolbar (Cmd/Ctrl + Shift + M)
# - Test iPhone SE (smallest)
# - Test iPad Pro (largest)
# - Test landscape and portrait- Chrome/Edge: F12 → Toggle device toolbar icon (or Ctrl+Shift+M)
- Firefox: F12 → Responsive Design Mode icon (or Ctrl+Shift+M)
- Safari: Develop menu → Enter Responsive Design Mode
Add to src/styles/globals.css:
/* Safe area padding for notched devices */
@supports (padding: env(safe-area-inset-bottom)) {
.pb-safe {
padding-bottom: env(safe-area-inset-bottom);
}
}
/* Prevent overscroll bounce on mobile */
html, body {
overscroll-behavior-y: none;
}Fix: Add pb-16 md:pb-0 to main content area
Fix: Add overflow-x-hidden to body
Fix: Ensure ChevronDown icon is visible on mobile in topbar
Fix: FullScreenOverlay always has X button by default
- Bottom nav appears on mobile (<768px)
- Bottom nav hidden on desktop (≥768px)
- All 5 tabs clickable
- Badge shows on Chats tab
- More dropdown opens
- User dropdown in topbar works
- Mobile menu items appear in dropdown
- Full-screen overlays have cancel button
- No content overflow
- No horizontal scroll
✅ Components created ✅ Topbar updated with mobile menu ✅ Documentation complete ⏳ Integration into main-layout.tsx (follow steps above) ⏳ Build and test
- Follow integration steps above
- Run
npm run buildto check for errors - Test on mobile devices
- Adjust styling as needed
- Done! 🎉