Fix mobile / desktop navigation
This commit is contained in:
parent
9722da5038
commit
8209f4f0f9
@ -1,5 +1,5 @@
|
|||||||
div {
|
div {
|
||||||
box-sizing: border-box
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.TabPanel {
|
.TabPanel {
|
||||||
@ -68,22 +68,27 @@ div {
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
overflow-x: visible;
|
overflow-x: visible;
|
||||||
min-width: 10rem;
|
min-width: 10rem;
|
||||||
width: 100%;
|
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prevent toolbar from shrinking vertically when media < 600px */
|
.MenuCard.MuiCard-root {
|
||||||
.MuiToolbar-root {
|
display: flex;
|
||||||
min-height: 56px !important;
|
flex-direction: column;
|
||||||
padding-left: 16px !important;
|
min-width: 10rem;
|
||||||
padding-right: 16px !important;
|
flex-grow: 1;
|
||||||
|
background-color: #1A2536; /* Midnight Blue */
|
||||||
|
color: #D3CDBF; /* Warm Gray */
|
||||||
|
border-radius: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
.MenuCard.MuiCard-root button {
|
||||||
.Controls {
|
min-height: 64px;
|
||||||
width: 600px; /* or whatever you prefer for a desktop */
|
}
|
||||||
max-width: 80vw; /* Optional: Prevent it from taking up too much space */
|
/* Prevent toolbar from shrinking vertically when media < 600px */
|
||||||
}
|
.MuiToolbar-root {
|
||||||
|
min-height: 72px !important;
|
||||||
|
padding-left: 16px !important;
|
||||||
|
padding-right: 16px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.Conversation {
|
.Conversation {
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import React, { useState, useEffect, useRef, useCallback, ReactElement } from 'react';
|
import React, { useState, useEffect, useRef, useCallback, ReactElement } from 'react';
|
||||||
|
import useMediaQuery from '@mui/material/useMediaQuery';
|
||||||
import FormGroup from '@mui/material/FormGroup';
|
import FormGroup from '@mui/material/FormGroup';
|
||||||
|
import Card from '@mui/material/Card';
|
||||||
import FormControlLabel from '@mui/material/FormControlLabel';
|
import FormControlLabel from '@mui/material/FormControlLabel';
|
||||||
import { styled } from '@mui/material/styles';
|
import { styled } from '@mui/material/styles';
|
||||||
import Avatar from '@mui/material/Avatar';
|
import Avatar from '@mui/material/Avatar';
|
||||||
@ -21,13 +23,13 @@ import AppBar from '@mui/material/AppBar';
|
|||||||
import Drawer from '@mui/material/Drawer';
|
import Drawer from '@mui/material/Drawer';
|
||||||
import Toolbar from '@mui/material/Toolbar';
|
import Toolbar from '@mui/material/Toolbar';
|
||||||
import SettingsIcon from '@mui/icons-material/Settings';
|
import SettingsIcon from '@mui/icons-material/Settings';
|
||||||
import CloseIcon from '@mui/icons-material/Close';
|
|
||||||
import IconButton from '@mui/material/IconButton';
|
import IconButton from '@mui/material/IconButton';
|
||||||
import Box from '@mui/material/Box';
|
import Box from '@mui/material/Box';
|
||||||
import CssBaseline from '@mui/material/CssBaseline';
|
import CssBaseline from '@mui/material/CssBaseline';
|
||||||
import ResetIcon from '@mui/icons-material/History';
|
import ResetIcon from '@mui/icons-material/History';
|
||||||
import SendIcon from '@mui/icons-material/Send';
|
import SendIcon from '@mui/icons-material/Send';
|
||||||
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
|
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
|
||||||
|
import MenuIcon from '@mui/icons-material/Menu';
|
||||||
|
|
||||||
import PropagateLoader from "react-spinners/PropagateLoader";
|
import PropagateLoader from "react-spinners/PropagateLoader";
|
||||||
|
|
||||||
@ -320,8 +322,8 @@ const App = () => {
|
|||||||
const [processing, setProcessing] = useState(false);
|
const [processing, setProcessing] = useState(false);
|
||||||
const [sessionId, setSessionId] = useState<string | undefined>(undefined);
|
const [sessionId, setSessionId] = useState<string | undefined>(undefined);
|
||||||
const [connectionBase,] = useState<string>(getConnectionBase(window.location))
|
const [connectionBase,] = useState<string>(getConnectionBase(window.location))
|
||||||
const [mobileOpen, setMobileOpen] = useState(false);
|
const [menuOpen, setMenuOpen] = useState(false);
|
||||||
const [isClosing, setIsClosing] = useState(false);
|
const [isMenuClosing, setIsMenuClosing] = useState(false);
|
||||||
const [snackOpen, setSnackOpen] = useState(false);
|
const [snackOpen, setSnackOpen] = useState(false);
|
||||||
const [snackMessage, setSnackMessage] = useState("");
|
const [snackMessage, setSnackMessage] = useState("");
|
||||||
const [snackSeverity, setSnackSeverity] = useState<SeverityType>("success");
|
const [snackSeverity, setSnackSeverity] = useState<SeverityType>("success");
|
||||||
@ -343,6 +345,8 @@ const App = () => {
|
|||||||
const [resume, setResume] = useState<MessageData | undefined>(undefined);
|
const [resume, setResume] = useState<MessageData | undefined>(undefined);
|
||||||
const [facts, setFacts] = useState<MessageData | undefined>(undefined);
|
const [facts, setFacts] = useState<MessageData | undefined>(undefined);
|
||||||
const timerRef = useRef<any>(null);
|
const timerRef = useRef<any>(null);
|
||||||
|
const isDesktop = useMediaQuery('(min-width:600px)');
|
||||||
|
const prevIsDesktopRef = useRef<boolean>(isDesktop);
|
||||||
|
|
||||||
const startCountdown = (seconds: number) => {
|
const startCountdown = (seconds: number) => {
|
||||||
if (timerRef.current) clearInterval(timerRef.current);
|
if (timerRef.current) clearInterval(timerRef.current);
|
||||||
@ -400,6 +404,17 @@ const App = () => {
|
|||||||
setSnackOpen(true);
|
setSnackOpen(true);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (prevIsDesktopRef.current === isDesktop)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (menuOpen) {
|
||||||
|
setMenuOpen(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
prevIsDesktopRef.current = isDesktop;
|
||||||
|
}, [isDesktop, setMenuOpen, menuOpen])
|
||||||
|
|
||||||
// Get the system information
|
// Get the system information
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (systemInfo !== undefined || sessionId === undefined) {
|
if (systemInfo !== undefined || sessionId === undefined) {
|
||||||
@ -810,28 +825,76 @@ const App = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDrawerClose = () => {
|
const handleMenuClose = () => {
|
||||||
setIsClosing(true);
|
setIsMenuClosing(true);
|
||||||
setMobileOpen(false);
|
setMenuOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDrawerTransitionEnd = () => {
|
const handleMenuTransitionEnd = () => {
|
||||||
setIsClosing(false);
|
setIsMenuClosing(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDrawerToggle = () => {
|
const handleMenuToggle = () => {
|
||||||
if (!isClosing) {
|
if (!isMenuClosing) {
|
||||||
setMobileOpen(!mobileOpen);
|
setMenuOpen(!menuOpen);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const drawer = (
|
const settingsPanel = (
|
||||||
<>
|
<>
|
||||||
{sessionId !== undefined && systemInfo !== undefined &&
|
{sessionId !== undefined && systemInfo !== undefined &&
|
||||||
<Controls {...{ messageHistoryLength, setMessageHistoryLength, tools, rags, reset, systemPrompt, toggleTool, toggleRag, setSystemPrompt, systemInfo }} />}
|
<Controls {...{ messageHistoryLength, setMessageHistoryLength, tools, rags, reset, systemPrompt, toggleTool, toggleRag, setSystemPrompt, systemInfo }} />}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handleTabChange = (event: React.SyntheticEvent, newValue: number) => {
|
||||||
|
setTab(newValue);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const menuDrawer = (
|
||||||
|
<Card className="MenuCard">
|
||||||
|
<Tabs sx={{ display: "flex", flexGrow: 1 }}
|
||||||
|
orientation="vertical"
|
||||||
|
value={tab}
|
||||||
|
indicatorColor="secondary"
|
||||||
|
textColor="inherit"
|
||||||
|
variant="scrollable"
|
||||||
|
allowScrollButtonsMobile
|
||||||
|
onChange={handleTabChange}
|
||||||
|
aria-label="Backstory navigation">
|
||||||
|
<Tab sx={{ fontSize: '1rem' }} label="Backstory"
|
||||||
|
value={0}
|
||||||
|
icon={
|
||||||
|
<Avatar sx={{
|
||||||
|
width: 24,
|
||||||
|
height: 24
|
||||||
|
}}
|
||||||
|
variant="rounded"
|
||||||
|
alt="Backstory logo"
|
||||||
|
src="/logo192.png" />
|
||||||
|
}
|
||||||
|
iconPosition="start" />
|
||||||
|
<Tab
|
||||||
|
value={1}
|
||||||
|
sx={{ fontSize: '1rem' }} wrapped
|
||||||
|
label="Resume Builder"
|
||||||
|
/>
|
||||||
|
<Tab
|
||||||
|
value={2}
|
||||||
|
sx={{ fontSize: '1rem' }} wrapped
|
||||||
|
label="Context Visualizer"
|
||||||
|
/>
|
||||||
|
<Tab
|
||||||
|
value={3}
|
||||||
|
sx={{ fontSize: '1rem' }} label="About" />
|
||||||
|
<Tab
|
||||||
|
value={4}
|
||||||
|
sx={{ fontSize: '1rem' }} icon={<SettingsIcon />} />
|
||||||
|
</Tabs>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
|
||||||
const submitQuery = (text: string) => {
|
const submitQuery = (text: string) => {
|
||||||
sendQuery(text);
|
sendQuery(text);
|
||||||
}
|
}
|
||||||
@ -1037,10 +1100,6 @@ const App = () => {
|
|||||||
setSnackOpen(false);
|
setSnackOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleTabChange = (event: React.SyntheticEvent, newValue: number) => {
|
|
||||||
setTab(newValue);
|
|
||||||
};
|
|
||||||
|
|
||||||
/* toolbar height is 56px + 8px margin-top */
|
/* toolbar height is 56px + 8px margin-top */
|
||||||
const Offset = styled('div')(({ theme }) => ({ ...theme.mixins.toolbar, minHeight: '64px', height: '64px' }));
|
const Offset = styled('div')(({ theme }) => ({ ...theme.mixins.toolbar, minHeight: '64px', height: '64px' }));
|
||||||
|
|
||||||
@ -1056,45 +1115,67 @@ const App = () => {
|
|||||||
>
|
>
|
||||||
<Toolbar>
|
<Toolbar>
|
||||||
{
|
{
|
||||||
mobileOpen === false &&
|
<Box sx={{ display: "flex", flexGrow: 1, flexDirection: "row" }}>
|
||||||
<Box sx={{ display: "flex", flexGrow: 1 }}>
|
{
|
||||||
<Tabs value={tab} indicatorColor="secondary"
|
!isDesktop &&
|
||||||
textColor="inherit"
|
|
||||||
variant="scrollable"
|
|
||||||
allowScrollButtonsMobile
|
|
||||||
onChange={handleTabChange} aria-label="Backstory navigation">
|
|
||||||
<Tab label="Backstory" icon={<Avatar sx={{ width: 24, height: 24 }} variant="rounded" alt="Backstory logo" src="/logo192.png" />} iconPosition="start" />
|
|
||||||
<Tab wrapped label="Resume Builder" />
|
|
||||||
<Tab wrapped label="Context Visualizer" />
|
|
||||||
<Tab label="About" />
|
|
||||||
</Tabs>
|
|
||||||
|
|
||||||
<Tooltip title="LLM Settings">
|
|
||||||
<IconButton
|
<IconButton
|
||||||
|
sx={{ display: "flex", margin: 'auto 0px' }}
|
||||||
|
size="large"
|
||||||
|
edge="start"
|
||||||
color="inherit"
|
color="inherit"
|
||||||
aria-label="open drawer"
|
onClick={handleMenuToggle}
|
||||||
edge="end"
|
|
||||||
onClick={handleDrawerToggle}
|
|
||||||
>
|
>
|
||||||
<SettingsIcon />
|
<Tooltip title="Navigation">
|
||||||
|
<MenuIcon />
|
||||||
|
</Tooltip>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
}
|
||||||
|
|
||||||
|
{ menuOpen === false &&
|
||||||
|
<Tabs sx={{ display: "flex", flexGrow: 1 }}
|
||||||
|
value={tab}
|
||||||
|
indicatorColor="secondary"
|
||||||
|
textColor="inherit"
|
||||||
|
variant="fullWidth"
|
||||||
|
allowScrollButtonsMobile
|
||||||
|
onChange={handleTabChange}
|
||||||
|
aria-label="Backstory navigation">
|
||||||
|
<Tab sx={{ fontSize: '1rem' }} label="Backstory"
|
||||||
|
value={0}
|
||||||
|
icon={
|
||||||
|
<Avatar sx={{
|
||||||
|
width: 24,
|
||||||
|
height: 24
|
||||||
|
}}
|
||||||
|
variant="rounded"
|
||||||
|
alt="Backstory logo"
|
||||||
|
src="/logo192.png" />
|
||||||
|
}
|
||||||
|
iconPosition="start" />
|
||||||
|
{ isDesktop &&
|
||||||
|
<Tab
|
||||||
|
value={1}
|
||||||
|
sx={{ fontSize: '1rem' }} wrapped
|
||||||
|
label="Resume Builder"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
{isDesktop &&
|
||||||
|
<Tab
|
||||||
|
value={2}
|
||||||
|
sx={{ fontSize: '1rem' }} wrapped
|
||||||
|
label="Context Visualizer"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
<Tab
|
||||||
|
value={3}
|
||||||
|
sx={{ fontSize: '1rem' }} label="About" />
|
||||||
|
<Tab
|
||||||
|
value={4}
|
||||||
|
sx={{ flexShrink: 1, flexGrow: 0, fontSize: '1rem' }} icon={<SettingsIcon />}/>
|
||||||
|
</Tabs>
|
||||||
|
}
|
||||||
</Box>
|
</Box>
|
||||||
}
|
}
|
||||||
{
|
|
||||||
mobileOpen === true &&
|
|
||||||
<Tooltip title="Close Settings">
|
|
||||||
<IconButton
|
|
||||||
color="inherit"
|
|
||||||
aria-label="close drawer"
|
|
||||||
edge="end"
|
|
||||||
onClick={handleDrawerToggle}
|
|
||||||
sx={{ mr: 2, right: 0, position: "absolute" }}
|
|
||||||
>
|
|
||||||
<CloseIcon />
|
|
||||||
</IconButton>
|
|
||||||
</Tooltip>
|
|
||||||
}
|
|
||||||
</Toolbar>
|
</Toolbar>
|
||||||
|
|
||||||
</AppBar>
|
</AppBar>
|
||||||
@ -1106,13 +1187,12 @@ const App = () => {
|
|||||||
component="nav"
|
component="nav"
|
||||||
aria-label="mailbox folders"
|
aria-label="mailbox folders"
|
||||||
>
|
>
|
||||||
{/* The implementation can be swapped with js to avoid SEO duplication of links. */}
|
|
||||||
<Drawer
|
<Drawer
|
||||||
container={window.document.body}
|
container={window.document.body}
|
||||||
variant="temporary"
|
variant="temporary"
|
||||||
open={mobileOpen}
|
open={menuOpen}
|
||||||
onTransitionEnd={handleDrawerTransitionEnd}
|
onTransitionEnd={handleMenuTransitionEnd}
|
||||||
onClose={handleDrawerClose}
|
onClose={handleMenuClose}
|
||||||
sx={{
|
sx={{
|
||||||
display: 'block',
|
display: 'block',
|
||||||
'& .MuiDrawer-paper': { boxSizing: 'border-box' },
|
'& .MuiDrawer-paper': { boxSizing: 'border-box' },
|
||||||
@ -1124,7 +1204,7 @@ const App = () => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Toolbar />
|
<Toolbar />
|
||||||
{drawer}
|
{menuDrawer}
|
||||||
</Drawer>
|
</Drawer>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
@ -1203,6 +1283,14 @@ const App = () => {
|
|||||||
</Box>
|
</Box>
|
||||||
</CustomTabPanel>
|
</CustomTabPanel>
|
||||||
|
|
||||||
|
<CustomTabPanel tab={tab} index={4}>
|
||||||
|
<Box className="ChatBox">
|
||||||
|
<Box className="Conversation">
|
||||||
|
{ settingsPanel }
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</CustomTabPanel>
|
||||||
|
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Snackbar open={snackOpen} autoHideDuration={(snackSeverity === "success" || snackSeverity === "info") ? 1500 : 6000} onClose={handleSnackClose}>
|
<Snackbar open={snackOpen} autoHideDuration={(snackSeverity === "success" || snackSeverity === "info") ? 1500 : 6000} onClose={handleSnackClose}>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user