This commit is contained in:
2025-12-09 05:39:35 -06:00
parent caf2c6481f
commit 40db2495f2

View File

@@ -2,7 +2,7 @@ import React, { useContext, useEffect, useRef, useState } from "react";
import styled, { ThemeContext } from "styled-components";
import { Formik, Form, Field, ErrorMessage } from "formik";
import * as Yup from "yup";
import { AttachFile, Delete, Send } from "@mui/icons-material"; // Keeping icons for now, can replace later if needed
import { AttachFile, Delete, Send, Menu } from "@mui/icons-material"; // Keeping icons for now, can replace later if needed
import { Tooltip } from "@mui/material";
import Markdown from "markdown-to-jsx";
@@ -36,7 +36,7 @@ const PageContainer = styled.div`
/* background-color: ${({ theme }) => theme.colors.background}; Removed to show particles */
`;
const Sidebar = styled.div`
const Sidebar = styled.div<{ $isOpen: boolean }>`
width: 280px;
height: 100%;
background: ${({ theme }) => theme.darkMode ? 'rgba(0, 0, 0, 0.6)' : 'rgba(255, 255, 255, 0.6)'};
@@ -46,12 +46,61 @@ const Sidebar = styled.div`
flex-direction: column;
padding: 1rem;
padding-top: 5rem; // Account for header
z-index: 10;
z-index: 20;
transition: transform 0.3s ease;
@media (max-width: 768px) {
position: absolute;
transform: translateX(-100%);
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'};
}
`;
const MobileSidebarToggle = styled.button`
display: none;
position: absolute;
top: 5.5rem; /* Below header */
left: 1rem;
z-index: 15;
padding: 0.5rem 1rem;
background: ${({ theme }) => theme.main};
color: white;
border: none;
border-radius: 2rem;
font-weight: 600;
box-shadow: 0 4px 12px rgba(0,0,0,0.2);
cursor: pointer;
transition: all 0.2s ease;
&:hover {
transform: translateY(-2px);
box-shadow: 0 6px 16px rgba(0,0,0,0.3);
}
@media (max-width: 768px) {
display: flex;
align-items: center;
gap: 0.5rem;
}
`;
const Overlay = styled.div<{ $isOpen: boolean }>`
display: none;
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(2px);
z-index: 15;
opacity: ${({ $isOpen }) => $isOpen ? 1 : 0};
pointer-events: ${({ $isOpen }) => $isOpen ? 'auto' : 'none'};
transition: opacity 0.3s ease;
@media (max-width: 768px) {
display: block;
}
`;
@@ -266,6 +315,7 @@ const AsyncDashboardInner = ({ }): JSX.Element => {
const conversationRef = useRef(conversationDetails);
const theme = useContext(ThemeContext);
const textareaRef = useRef<HTMLTextAreaElement>(null);
const [isSidebarOpen, setIsSidebarOpen] = useState(false);
async function GetAnnouncements() {
const response: AxiosResponse<AnnouncementType[]> =
@@ -326,8 +376,18 @@ const AsyncDashboardInner = ({ }): JSX.Element => {
<ParticleBackground />
<Header2 />
<Sidebar>
<NewChatButton onClick={() => setSelectedConversation(undefined)}>
<Overlay $isOpen={isSidebarOpen} onClick={() => setIsSidebarOpen(false)} />
<MobileSidebarToggle onClick={() => setIsSidebarOpen(true)}>
<Menu fontSize="small" />
<span>Conversations</span>
</MobileSidebarToggle>
<Sidebar $isOpen={isSidebarOpen}>
<NewChatButton onClick={() => {
setSelectedConversation(undefined);
setIsSidebarOpen(false);
}}>
+ New Chat
</NewChatButton>
<div style={{ overflowY: 'auto', flex: 1 }}>
@@ -335,7 +395,10 @@ const AsyncDashboardInner = ({ }): JSX.Element => {
<ConversationItem
key={convo.id}
$active={convo.id === selectedConversation}
onClick={() => setSelectedConversation(convo.id)}
onClick={() => {
setSelectedConversation(convo.id);
setIsSidebarOpen(false);
}}
>
<ConversationTitle>{convo.title || "New Conversation"}</ConversationTitle>
{convo.id === selectedConversation && (