chore: Make the main container dynamic based on the with of the menudrawer

This commit is contained in:
Rodolfo Ruiz
2025-08-29 21:59:16 -06:00
parent 2eeb0b42d8
commit 2116e134a9
4 changed files with 104 additions and 101 deletions

View File

@@ -1,40 +1,62 @@
import { useState } from 'react' import { useState } from 'react';
import './App.css' import { Box, useMediaQuery } from '@mui/material';
import { useTheme } from '@mui/material/styles';
import AppHeader from './components/AppHeader'; import AppHeader from './components/AppHeader';
import MenuDrawerPrivate, { OPEN_WIDTH, MINI_WIDTH } from './components/MenuDrawerPrivate';
import Footer from './components/Footer'; import Footer from './components/Footer';
import Box from '@mui/material/Box';
import Clients from './private/clients/Clients';
import Dashboard from './private/dashboard/Dashboard'; import Dashboard from './private/dashboard/Dashboard';
import UserManagement from './private/users/UserManagement'; import UserManagement from './private/users/UserManagement';
import LoginPage from './private/LoginPage'; import LoginPage from './private/LoginPage';
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom'; import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
import { useAuth } from './context/AuthContext'; import { useAuth } from './context/AuthContext';
const DRAWER_EXPANDED = OPEN_WIDTH;
const DRAWER_COLLAPSED = MINI_WIDTH;
const APPBAR_HEIGHT = 64;
function PrivateRoute({ children }) { function PrivateRoute({ children }) {
const { user } = useAuth(); const { user } = useAuth();
return user ? children : <Navigate to="/login" replace />; return user ? children : <Navigate to="/login" replace />;
} }
function App() { export default function App() {
const theme = useTheme();
const isMobile = useMediaQuery('(max-width:900px)');
const [zone, setZone] = useState('public'); // public | restricted | private const [zone, setZone] = useState('public'); // public | restricted | private
const [drawerExpanded, setDrawerExpanded] = useState(true);
const [currentView, setCurrentView] = useState('Dashboard'); const [currentView, setCurrentView] = useState('Dashboard');
const mainLeft = isMobile ? 0 : (drawerExpanded ? DRAWER_EXPANDED : DRAWER_COLLAPSED);
return ( return (
<> <>
<AppHeader
zone="private"
onSelectMenuItem={setCurrentView}
drawerExpanded={drawerExpanded}
/>
<MenuDrawerPrivate
onSelect={(value) => {
setCurrentView(value === '/users/UserManagement' ? 'UserManagement' : value);
}}
onExpandedChange={(expanded) => setDrawerExpanded(expanded)}
/>
<Box <Box
component="main"
sx={{ sx={{
display: 'flex', ml: { xs: 0, md: `${mainLeft}px` },
flexDirection: 'column', mt: `${APPBAR_HEIGHT}px`,
minHeight: '100vh', // full height of the viewport p: 2,
transition: theme.transitions.create('margin-left', {
duration: theme.transitions.duration.standard,
easing: theme.transitions.easing.sharp,
}),
}} }}
> >
<AppHeader zone={zone} onSelectMenuItem={(view) => setCurrentView(view)} />
<Box sx={{ height: 64 }} />
<Box component="main" sx={{ flex: 1, p: 2 }}>
<Routes> <Routes>
<Route path="/login" element={<LoginPage />} /> <Route path="/login" element={<LoginPage />} />
@@ -56,10 +78,7 @@ function App() {
<Box sx={{ height: 64 }} /> <Box sx={{ height: 64 }} />
<Footer zone={zone} /> <Footer zone={zone} />
</Box>
</> </>
) );
} }
export default App

View File

@@ -1,59 +1,40 @@
import { useState } from 'react';
import { AppBar, Toolbar, Typography, IconButton, Box, Avatar } from '@mui/material';
import MenuDrawer from './MenuDrawer';
import MenuDrawerPrivate from './MenuDrawerPrivate';
import { useAuth } from '../context/AuthContext'; import { useAuth } from '../context/AuthContext';
import { useNavigate } from 'react-router-dom'; import { AppBar, Toolbar, Typography, IconButton, Box, Avatar, useMediaQuery } from '@mui/material';
import { useTheme } from '@mui/material/styles';
import { OPEN_WIDTH, MINI_WIDTH } from './MenuDrawerPrivate';
export default function AppHeader({ zone = 'public', onSelectMenuItem }) {
const bgColor = { export default function AppHeader({ drawerExpanded = true, currentPage = 'Dashboard' }) {
public: 'white', const theme = useTheme();
restricted: 'white', const isMobile = useMediaQuery('(max-width:900px)');
private: 'white',
};
const [drawerExpanded, setDrawerExpanded] = useState(true);
const [currentPage, setCurrentPage] = useState('Dashboard');
const { user } = useAuth(); const { user } = useAuth();
const isPrivate = zone === 'private';
const isRestricted = zone === 'restricted';
const isPublic = zone === 'public';
const navigate = useNavigate(); const leftOffset = isMobile ? 0 : (drawerExpanded ? OPEN_WIDTH : MINI_WIDTH);
const handleMenuSelect = (page) => {
setCurrentPage(page);
onSelectMenuItem?.(page);
};
return ( return (
<AppBar position="fixed" <AppBar
position="fixed"
sx={{ sx={{
textAlign: 'center', background: 'white',
backgroundColor: bgColor[zone], color: '#40120E',
fontSize: { xs: '0.75rem', md: '1rem' },
boxShadow: '0px 2px 4px rgba(0,0,0,0.1)', boxShadow: '0px 2px 4px rgba(0,0,0,0.1)',
border: 'none',
width: '100%',
left: 0,
right: 0,
}} >
<Toolbar disableGutters sx={{ justifyContent: 'flex-start', alignItems: 'center', flexWrap: 'nowrap', pl: 0, pr: 0, minHeight: 64, width: '100%', '&.MuiToolbar-gutters': { pl: 0, pr: 0 }, position: 'relative', }}>
<Box
sx={{
display: 'flex',
alignItems: 'center',
ml: `${drawerExpanded ? '300px' : '72px'}`,
}} }}
> >
<Typography <Toolbar sx={{ minHeight: 64 }}>
variant="h6" <Box
noWrap sx={{
sx={{ color: '#40120EFF', fontWeight: 'light', fontSize: '30px' }} ml: `${leftOffset}px`,
transition: theme.transitions.create('margin-left', {
duration: theme.transitions.duration.standard,
easing: theme.transitions.easing.sharp,
}),
display: 'flex',
alignItems: 'center',
flexGrow: 1,
}}
> >
<Typography variant="h6" sx={{ fontWeight: 600 }}>
{currentPage} {currentPage}
</Typography> </Typography>
</Box> </Box>
@@ -87,12 +68,6 @@ export default function AppHeader({ zone = 'public', onSelectMenuItem }) {
)} )}
</Box> </Box>
<MenuDrawerPrivate
zone="private"
onSelect={handleMenuSelect}
onExpandedChange={(expanded) => setDrawerExpanded(expanded)}
/>
</Toolbar> </Toolbar>
</AppBar> </AppBar>
); );

View File

@@ -14,8 +14,8 @@ import SettingsIcon from '@mui/icons-material/Settings';
import ExpandLess from '@mui/icons-material/ExpandLess'; import ExpandLess from '@mui/icons-material/ExpandLess';
import ExpandMore from '@mui/icons-material/ExpandMore'; import ExpandMore from '@mui/icons-material/ExpandMore';
const OPEN_WIDTH = 400; export const OPEN_WIDTH = 450;
const MINI_WIDTH = 72; export const MINI_WIDTH = 72;
const menuData = [ const menuData = [
{ {
@@ -37,13 +37,15 @@ const menuData = [
{ {
title: 'Category Dictionary', title: 'Category Dictionary',
children: [ children: [
{ title: 'Categories' }, { title: 'Categories' }
{ title: 'Products' },
{ title: 'All Assets Library' },
{ title: 'Media Management' },
{ title: 'Product Collections' },
] ]
} },
{ title: 'Products',
children: [
{ title: 'AR Assets Library Management' },
{ title: 'Media Management' },
] },
{ title: 'Product Collections' },
] ]
} }
] ]
@@ -52,13 +54,17 @@ const menuData = [
title: 'Customers', title: 'Customers',
icon: <PeopleAltIcon />, icon: <PeopleAltIcon />,
children: [ children: [
{ title: 'CRM' }, { title: 'CRM',
{ title: 'Customer List' },
{
title: 'Projects',
children: [ children: [
{ title: 'Customer List' },
{ title: 'Projects' },
{ title: 'Customer Collections' }, { title: 'Customer Collections' },
{ title: 'Sales' }, ]
},
{
title: 'Sales',
children: [
{ title: 'Quotes' }, { title: 'Quotes' },
{ title: 'Orders' }, { title: 'Orders' },
] ]
@@ -80,11 +86,14 @@ const menuData = [
icon: <AdminPanelSettingsIcon />, icon: <AdminPanelSettingsIcon />,
children: [ children: [
{ title: 'Users Management' }, { title: 'Users Management' },
{ title: 'Access Control' }, { title: 'Access Control',
children: [
{ title: 'Roles' }, { title: 'Roles' },
{ title: 'Permissions' }, { title: 'Permissions' },
] ]
}, },
]
},
{ {
title: 'Settings', title: 'Settings',
icon: <SettingsIcon />, icon: <SettingsIcon />,

View File

@@ -13,7 +13,7 @@ export default function LoginPage() {
const navigate = useNavigate(); const navigate = useNavigate();
return ( return (
<Box display="flex" justifyContent="center" alignItems="center" Height="100vh"> <Box display="flex" justifyContent="center" alignItems="center" height="100vh">
<Paper sx={{ p: 4, borderRadius: 2, boxShadow: 3, textAlign: 'center' }}> <Paper sx={{ p: 4, borderRadius: 2, boxShadow: 3, textAlign: 'center' }}>
<Typography variant="h5" mb={2}>Login to Dream Views</Typography> <Typography variant="h5" mb={2}>Login to Dream Views</Typography>