diff --git a/frontend/src/App.css b/frontend/src/App.css index 8a880de..95de93f 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -40,3 +40,46 @@ .read-the-docs { color: #888; } + +/* Mobile-friendly conversation sidebar */ +.conversation-sidebar { + width: 380px; + min-width: 380px; + max-width: 380px; + flex-shrink: 0; + transition: transform 0.3s ease-in-out; +} + +/* Mobile styles - screens smaller than 768px (Bootstrap md breakpoint) */ +@media (max-width: 767.98px) { + .conversation-sidebar { + position: absolute; + top: 0; + left: 0; + width: 100%; + max-width: 100%; + min-width: 100%; + height: 100%; + z-index: 1000; + transform: translateX(-100%); + } + + .conversation-sidebar.show { + transform: translateX(0); + } + + .message-thread-container { + width: 100%; + } +} + +/* Tablet and desktop - show both sidebar and content */ +@media (min-width: 768px) { + .conversation-sidebar { + transform: translateX(0) !important; + } + + .mobile-back-button { + display: none !important; + } +} diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index b69b65a..76cdc5b 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -29,6 +29,9 @@ function App() { const [showPasswordModal, setShowPasswordModal] = useState(false) const [searchFilter, setSearchFilter] = useState('') + // Mobile sidebar state + const [showSidebar, setShowSidebar] = useState(true) + // Search state (persisted across tab switches) const [searchQuery, setSearchQuery] = useState('') const [searchResults, setSearchResults] = useState([]) @@ -54,7 +57,7 @@ function App() { fetchConversations() }, [startDate, endDate]) - // Sync selected conversation from URL + // Sync selected conversation from URL and manage sidebar visibility useEffect(() => { const match = location.pathname.match(/^\/conversation\/(.+)$/) if (match) { @@ -67,8 +70,11 @@ function App() { // If conversation not found in list, create a minimal conversation object setSelectedConversation({ address, contact_name: address, type: 'message' }) } - } else if (location.pathname === '/' || location.pathname === '/conversations') { + } else { + // Not viewing a specific conversation setSelectedConversation(null) + // Show sidebar when navigating to any non-conversation view + setShowSidebar(true) } }, [location.pathname, conversations]) @@ -109,6 +115,8 @@ function App() { const handleSelectConversation = (conversation) => { if (conversation) { navigate(`/conversation/${encodeURIComponent(conversation.address)}`) + // Hide sidebar on mobile when conversation is selected + setShowSidebar(false) } } @@ -262,11 +270,13 @@ function App() { {/* Main Content */} -
+
{activeView === 'conversations' ? ( <> {/* Conversation List */} -
+

@@ -298,7 +308,21 @@ function App() {

{/* Message Thread */} -
+
+ {/* Mobile back button */} + {selectedConversation && ( +
+ +
+ )}