Documentation Index
Fetch the complete documentation index at: https://mintlify.com/toryshchyn/cat-web/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The MasterLayout component provides the primary application structure for Cat Web. It includes a top AppBar with branding and user information, a responsive navigation drawer, and a content container for nested routes.
Source: src/components/MasterLayout.tsx
Key Features
- Top AppBar with application branding and user profile
- Right-side navigation drawer with menu items
- Responsive design with Material-UI components
- Integration with React Router for navigation
- Auth0 integration for authentication state
- Logout functionality
- Inventory catalogue branding
Props
This component does not accept any props. It’s a self-contained layout component.
const MasterLayout: React.FC = () => { ... }
Layout Structure
The component uses a flexbox layout with three main sections:
<Box sx={{ display: 'flex', flexDirection: 'column', minHeight: '100vh' }}>
{/* 1. AppBar - Fixed at top */}
<AppBar position="static">
...
</AppBar>
{/* 2. Drawer - Slides in from right */}
<Drawer anchor="right" open={drawerOpen}>
...
</Drawer>
{/* 3. Content - Grows to fill remaining space */}
<Container component="main" sx={{ flexGrow: 1, py: 3 }}>
<Outlet />
</Container>
</Box>
AppBar Section
The top bar displays application branding and authentication-dependent content:
Branding
<Box sx={{ display: 'flex', alignItems: 'center' }}>
<Inventory2Icon sx={{ mr: 1 }} />
<Typography variant="h6" component="div">
Inventory catalogue
</Typography>
</Box>
Authenticated User Display
When authenticated, the user’s name and menu icon are shown:
{isAuthenticated && !isLoading && (
<Box display="flex" alignItems="center">
<Typography variant="body1" sx={{ mr: 2 }}>
{user?.name}
</Typography>
<IconButton
color="inherit"
aria-label="open drawer"
edge="end"
onClick={toggleDrawer}
>
<MenuIcon />
</IconButton>
</Box>
)}
Unauthenticated State
For unauthenticated users, a login button is displayed:
{!isAuthenticated && !isLoading && (
<Box display="flex" alignItems="center">
<IconButton
color="inherit"
onClick={()=> loginWithPopup()}
>
Login
</IconButton>
</Box>
)}
Navigation Drawer
The drawer slides in from the right side and contains navigation links:
Drawer Configuration
<Drawer
anchor="right"
open={drawerOpen}
onClose={toggleDrawer}
>
<Box
sx={{ width: 250 }}
role="presentation"
onClick={toggleDrawer}
>
<List>
{/* Navigation items */}
</List>
</Box>
</Drawer>
Navigation Items
The drawer includes four navigation items:
-
Home - Links to
/
<ListItem>
<Link to="/" style={{ textDecoration: 'none', color: 'inherit', display: 'block', width: '100%' }}>
<ListItemButton>
<ListItemIcon>
<HomeIcon />
</ListItemIcon>
<ListItemText primary="Home" />
</ListItemButton>
</Link>
</ListItem>
-
Inventory - Links to
/dashboard
-
API tests - Links to
/api-tests
-
Logout - Triggers Auth0 logout
Logout Functionality
<ListItemButton onClick={() => {
logout({ logoutParams: { returnTo: window.location.origin } });
}}>
<ListItemIcon>
<LogoutIcon />
</ListItemIcon>
<ListItemText primary="Logout" />
</ListItemButton>
State Management
The component manages drawer state with React useState:
const [drawerOpen, setDrawerOpen] = useState(false);
const toggleDrawer = () => {
setDrawerOpen(!drawerOpen);
};
Auth0 Integration
The component uses the useAuth0 hook to access authentication state:
const { user, isAuthenticated, isLoading, loginWithPopup, logout } = useAuth0();
Usage with React Router
Basic Setup
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import MasterLayout from './components/MasterLayout';
import Home from './pages/Home';
import Dashboard from './pages/Dashboard';
import ApiTesting from './components/ApiTesting';
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<MasterLayout />}>
<Route index element={<Home />} />
<Route path="dashboard" element={<Dashboard />} />
<Route path="api-tests" element={<ApiTesting />} />
</Route>
</Routes>
</BrowserRouter>
);
}
With AuthGuard Protection
import AuthGuard from './components/AuthGuard';
import MasterLayout from './components/MasterLayout';
function App() {
return (
<Routes>
<Route path="/" element={
<AuthGuard component={<MasterLayout />} />
}>
<Route path="dashboard" element={<Dashboard />} />
<Route path="api-tests" element={<ApiTesting />} />
</Route>
</Routes>
);
}
Material-UI Components Used
The component leverages numerous Material-UI components:
Layout & Structure
AppBar: Top application bar
Toolbar: Container for AppBar content
Drawer: Sliding navigation panel
Box: Flexible container for layout
Container: Content container with max-width
Navigation
List: Container for navigation items
ListItem: Individual list item wrapper
ListItemButton: Clickable list item
ListItemIcon: Icon container in list items
ListItemText: Text content in list items
UI Elements
IconButton: Clickable icon buttons
Typography: Styled text components
Icons from @mui/icons-material
Inventory2Icon: App branding and inventory navigation
MenuIcon: Drawer toggle button
HomeIcon: Home navigation
LogoutIcon: Logout action
ApiIcon: API testing navigation
Responsive Design
The layout automatically adapts to different screen sizes:
- Mobile: Drawer provides compact navigation
- Desktop: Full AppBar with user information visible
- Flexbox: Content grows to fill available vertical space
sx={{ display: 'flex', flexDirection: 'column', minHeight: '100vh' }}
Complete Source Code
import React, { useState } from 'react';
import {
AppBar,
Toolbar,
IconButton,
Typography,
Drawer,
List,
ListItem,
ListItemButton,
ListItemIcon,
ListItemText,
Box,
Container
} from '@mui/material';
import Inventory2Icon from '@mui/icons-material/Inventory2';
import MenuIcon from '@mui/icons-material/Menu';
import HomeIcon from '@mui/icons-material/Home';
import LogoutIcon from '@mui/icons-material/Logout';
import ApiIcon from '@mui/icons-material/Api';
import { Outlet, Link } from 'react-router-dom';
import { useAuth0 } from '@auth0/auth0-react';
const MasterLayout: React.FC = () => {
const [drawerOpen, setDrawerOpen] = useState(false);
const { user, isAuthenticated, isLoading, loginWithPopup, logout } = useAuth0();
const toggleDrawer = () => {
setDrawerOpen(!drawerOpen);
};
return (
<Box sx={{ display: 'flex', flexDirection: 'column', minHeight: '100vh' }}>
<AppBar position="static">
<Toolbar sx={{ justifyContent: 'space-between' }}>
<Box sx={{ display: 'flex', alignItems: 'center' }}>
<Inventory2Icon sx={{ mr: 1 }} />
<Typography variant="h6" component="div">
Inventory catalogue
</Typography>
</Box>
{isAuthenticated && !isLoading && (
<Box display="flex" alignItems="center">
<Box sx={{ display: 'flex', alignItems: 'center' }}>
<Typography variant="body1" sx={{ mr: 2 }}>
{user?.name}
</Typography>
</Box>
<IconButton
color="inherit"
aria-label="open drawer"
edge="end"
onClick={toggleDrawer}
>
<MenuIcon />
</IconButton>
</Box>
)}
{!isAuthenticated && !isLoading && (
<Box display="flex" alignItems="center">
<IconButton
color="inherit"
aria-label="open drawer"
edge="end"
size="small"
onClick={()=> loginWithPopup()}
>
Login
</IconButton>
</Box>
)}
</Toolbar>
</AppBar>
<Drawer
anchor="right"
open={drawerOpen}
onClose={toggleDrawer}
>
<Box
sx={{ width: 250 }}
role="presentation"
onClick={toggleDrawer}
>
<List>
<ListItem>
<Link to="/" style={{ textDecoration: 'none', color: 'inherit', display: 'block', width: '100%' }}>
<ListItemButton>
<ListItemIcon>
<HomeIcon />
</ListItemIcon>
<ListItemText primary="Home" />
</ListItemButton>
</Link>
</ListItem>
<ListItem>
<Link to="/dashboard" style={{ textDecoration: 'none', color: 'inherit', display: 'block', width: '100%' }}>
<ListItemButton>
<ListItemIcon>
<Inventory2Icon />
</ListItemIcon>
<ListItemText primary="Inventory" />
</ListItemButton>
</Link>
</ListItem>
<ListItem>
<Link to="/api-tests" style={{ textDecoration: 'none', color: 'inherit', display: 'block', width: '100%' }}>
<ListItemButton>
<ListItemIcon>
<ApiIcon />
</ListItemIcon>
<ListItemText primary="API tests" />
</ListItemButton>
</Link>
</ListItem>
<ListItem>
<ListItemButton onClick={() => {
logout({ logoutParams: { returnTo: window.location.origin } });
}}>
<ListItemIcon>
<LogoutIcon />
</ListItemIcon>
<ListItemText primary="Logout" />
</ListItemButton>
</ListItem>
</List>
</Box>
</Drawer>
<Container component="main" sx={{ flexGrow: 1, py: 3 }}>
<Outlet />
</Container>
</Box>
);
};
export default MasterLayout;
Best Practices
- Consistent Layout: Use MasterLayout as the parent route for all authenticated pages
- Drawer State: The drawer automatically closes when clicking menu items
- Navigation Links: Use React Router’s
<Link> component for client-side navigation
- Logout Redirect: Always specify
returnTo parameter for proper logout redirect
- Loading States: Conditionally render UI based on
isLoading to prevent flashing