diff --git a/llm-fe/src/llm-fe/pages/AsyncDashboard2/AsyncDashboard2.tsx b/llm-fe/src/llm-fe/pages/AsyncDashboard2/AsyncDashboard2.tsx index 78da260..7c845fe 100644 --- a/llm-fe/src/llm-fe/pages/AsyncDashboard2/AsyncDashboard2.tsx +++ b/llm-fe/src/llm-fe/pages/AsyncDashboard2/AsyncDashboard2.tsx @@ -2,7 +2,7 @@ import React, { useContext, useEffect, useRef, useState } from "react"; import styled, { ThemeContext } from "styled-components"; import { Formik, Form, Field } from "formik"; import * as Yup from "yup"; -import { AttachFile, Delete, Send, Menu } from "@mui/icons-material"; // Keeping icons for now, can replace later if needed +import { AttachFile, Delete, Send, Menu, Close } from "@mui/icons-material"; // Keeping icons for now, can replace later if needed import { Tooltip } from "@mui/material"; import Markdown from "markdown-to-jsx"; @@ -44,10 +44,15 @@ const Sidebar = styled.div<{ $isOpen: boolean }>` transition: transform 0.3s ease; @media (max-width: 768px) { - position: absolute; + position: fixed; + top: 0; + left: 0; + width: min(85vw, 320px); + height: 100vh; transform: ${({ $isOpen }) => $isOpen ? 'translateX(0)' : 'translateX(-100%)'}; background: ${({ theme }) => theme.darkMode ? 'rgba(0, 0, 0, 0.95)' : 'rgba(255, 255, 255, 0.95)'}; box-shadow: ${({ $isOpen }) => $isOpen ? '0 0 20px rgba(0,0,0,0.5)' : 'none'}; + z-index: 120; } `; @@ -88,7 +93,7 @@ const Overlay = styled.div<{ $isOpen: boolean }>` height: 100vh; background: rgba(0, 0, 0, 0.5); backdrop-filter: blur(2px); - z-index: 15; + z-index: 110; opacity: ${({ $isOpen }) => $isOpen ? 1 : 0}; pointer-events: ${({ $isOpen }) => $isOpen ? 'auto' : 'none'}; transition: opacity 0.3s ease; @@ -98,6 +103,36 @@ const Overlay = styled.div<{ $isOpen: boolean }>` } `; +const MobileSidebarHeader = styled.div` + display: none; + + @media (max-width: 768px) { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 1rem; + color: ${({ theme }) => theme.colors.text}; + font-weight: 700; + font-size: 1rem; + } +`; + +const MobileSidebarCloseButton = styled.button` + display: none; + + @media (max-width: 768px) { + display: flex; + align-items: center; + justify-content: center; + border: none; + background: transparent; + color: ${({ theme }) => theme.colors.text}; + cursor: pointer; + border-radius: 999px; + padding: 0.3rem; + } +`; + const MainContent = styled.div` flex: 1; height: 100%; @@ -384,6 +419,12 @@ const AsyncDashboardInner = (): JSX.Element => { + + Conversations + setIsSidebarOpen(false)} aria-label="Close conversations drawer"> + + + { setSelectedConversation(undefined); setIsSidebarOpen(false); @@ -391,30 +432,41 @@ const AsyncDashboardInner = (): JSX.Element => { + New Chat
- {conversations.map((convo) => ( - { - setSelectedConversation(convo.id); - setIsSidebarOpen(false); - }} - > - {convo.title || "New Conversation"} - {convo.id === selectedConversation && ( - { - e.stopPropagation(); - deleteConversation(convo.id); - }} - style={{ padding: 4, width: 'auto', height: 'auto' }} - > - - - )} - - ))} + {conversations.length === 0 ? ( +
+ No conversations yet. Start with + New Chat. +
+ ) : ( + conversations.map((convo) => ( + { + setSelectedConversation(convo.id); + setIsSidebarOpen(false); + }} + > + {convo.title || "New Conversation"} + {convo.id === selectedConversation && ( + { + e.stopPropagation(); + deleteConversation(convo.id); + }} + style={{ padding: 4, width: 'auto', height: 'auto' }} + > + + + )} + + )) + )}