From 8f6c39c3f775cc7614eb547fece4569120110ecf Mon Sep 17 00:00:00 2001 From: James Ketrenos Date: Fri, 30 May 2025 02:46:13 -0700 Subject: [PATCH] Drawer opens and closes --- frontend/src/pages/CandidateChatPage.tsx | 212 +++++++++++++++++------ 1 file changed, 155 insertions(+), 57 deletions(-) diff --git a/frontend/src/pages/CandidateChatPage.tsx b/frontend/src/pages/CandidateChatPage.tsx index 34cbd3d..ba07375 100644 --- a/frontend/src/pages/CandidateChatPage.tsx +++ b/frontend/src/pages/CandidateChatPage.tsx @@ -15,8 +15,16 @@ import { Card, CardContent, Avatar, - Grid + Drawer, + useTheme, + useMediaQuery, + Fab } from '@mui/material'; +import { + ChevronLeft, + ChevronRight, + Chat as ChatIcon +} from '@mui/icons-material'; import { useUser } from 'hooks/useUser'; import { ChatMessageBase, ChatMessage, ChatSession } from 'types/types'; import { ConversationHandle } from 'components/Conversation'; @@ -27,13 +35,20 @@ import { CandidateSessionsResponse } from 'services/api-client'; import { CandidateInfo } from 'components/CandidateInfo'; import { useNavigate } from 'react-router-dom'; +const DRAWER_WIDTH = 300; +const HANDLE_WIDTH = 48; + const CandidateChatPage = forwardRef((props: BackstoryPageProps, ref) => { const { apiClient, candidate } = useUser(); const navigate = useNavigate(); + const theme = useTheme(); + const isMdUp = useMediaQuery(theme.breakpoints.up('md')); + const { setSnack, submitQuery, } = props; + const [sessions, setSessions] = useState(null); const [chatSession, setChatSession] = useState(null); const [messages, setMessages] = useState([]); @@ -42,6 +57,14 @@ const CandidateChatPage = forwardRef((pr const [streaming, setStreaming] = useState(false); const messagesEndRef = useRef(null); + // Drawer state - defaults to open on md+ screens or when no session is selected + const [drawerOpen, setDrawerOpen] = useState(() => isMdUp || !chatSession); + + // Update drawer state when screen size or session changes + useEffect(() => { + setDrawerOpen(isMdUp || !chatSession); + }, [isMdUp, chatSession]); + // Load sessions for the candidate const loadSessions = async () => { if (!candidate) return; @@ -156,69 +179,144 @@ const CandidateChatPage = forwardRef((pr navigate('/find-a-candidate'); } + const drawerContent = ( + + + Chat Sessions + {sessions && ( + + )} + + + + + + {sessions ? ( + + {sessions.sessions.data.map((session: any) => ( + { + setChatSession(session); + // Auto-close drawer on smaller screens when session is selected + if (!isMdUp) { + setDrawerOpen(false); + } + }} + sx={{ + mb: 1, + borderRadius: 1, + border: '1px solid', + borderColor: chatSession?.id === session.id ? 'primary.main' : 'divider', + cursor: 'pointer', + '&:hover': { + backgroundColor: 'action.hover' + } + }} + > + + + ))} + + ) : ( + + Enter a username and click "Load Sessions" + + )} + + + ); + + const drawerHandle = ( + + setDrawerOpen(!drawerOpen)} + sx={{ + borderRadius: '0 50% 50% 0', + width: 32, + height: 64, + minHeight: 64, + boxShadow: 2, + '&:hover': { + boxShadow: 4, + } + }} + > + {drawerOpen ? : } + + + ); + return ( {candidate && } - < Box sx={{ display: "flex", mt: 1, gap: 1, height: "100%" }}> - {/* Sessions Sidebar */} - - - Chat Sessions - {sessions && ( - - )} - + + {/* Drawer */} + + {drawerContent} + - - - - {sessions ? ( - - {sessions.sessions.data.map((session: any) => ( - setChatSession(session)} - sx={{ - mb: 1, - borderRadius: 1, - border: '1px solid', - borderColor: chatSession?.id === session.id ? 'primary.main' : 'divider', - cursor: 'pointer', - '&:hover': { - backgroundColor: 'action.hover' - } - }} - > - - - ))} - - ) : ( - - Enter a username and click "Load Sessions" - - )} - - + {/* Drawer Handle */} + {drawerHandle} {/* Chat Interface */} - + {chatSession?.id ? ( <> {/* Messages Area */}