init: add fuse-react v8.3.5 skeleton
This commit is contained in:
76
src/app/theme-layouts/layout1/Layout1.js
Normal file
76
src/app/theme-layouts/layout1/Layout1.js
Normal file
@@ -0,0 +1,76 @@
|
||||
import FuseDialog from '@fuse/core/FuseDialog';
|
||||
import { styled } from '@mui/material/styles';
|
||||
import FuseMessage from '@fuse/core/FuseMessage';
|
||||
import FuseSuspense from '@fuse/core/FuseSuspense';
|
||||
import AppContext from 'app/AppContext';
|
||||
import { memo, useContext } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { useRoutes } from 'react-router-dom';
|
||||
import { selectFuseCurrentLayoutConfig } from 'app/store/fuse/settingsSlice';
|
||||
import FooterLayout1 from './components/FooterLayout1';
|
||||
import LeftSideLayout1 from './components/LeftSideLayout1';
|
||||
import NavbarWrapperLayout1 from './components/NavbarWrapperLayout1';
|
||||
import RightSideLayout1 from './components/RightSideLayout1';
|
||||
import ToolbarLayout1 from './components/ToolbarLayout1';
|
||||
import SettingsPanel from '../shared-components/SettingsPanel';
|
||||
|
||||
const Root = styled('div')(({ theme, config }) => ({
|
||||
...(config.mode === 'boxed' && {
|
||||
clipPath: 'inset(0)',
|
||||
maxWidth: `${config.containerWidth}px`,
|
||||
margin: '0 auto',
|
||||
boxShadow: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',
|
||||
}),
|
||||
...(config.mode === 'container' && {
|
||||
'& .container': {
|
||||
maxWidth: `${config.containerWidth}px`,
|
||||
width: '100%',
|
||||
margin: '0 auto',
|
||||
},
|
||||
}),
|
||||
}));
|
||||
|
||||
function Layout1(props) {
|
||||
const config = useSelector(selectFuseCurrentLayoutConfig);
|
||||
const appContext = useContext(AppContext);
|
||||
const { routes } = appContext;
|
||||
|
||||
return (
|
||||
<Root id="fuse-layout" config={config} className="w-full flex">
|
||||
{config.leftSidePanel.display && <LeftSideLayout1 />}
|
||||
|
||||
<div className="flex flex-auto min-w-0">
|
||||
{config.navbar.display && config.navbar.position === 'left' && <NavbarWrapperLayout1 />}
|
||||
|
||||
<main id="fuse-main" className="flex flex-col flex-auto min-h-full min-w-0 relative z-10">
|
||||
{config.toolbar.display && (
|
||||
<ToolbarLayout1 className={config.toolbar.style === 'fixed' && 'sticky top-0'} />
|
||||
)}
|
||||
|
||||
<div className="sticky top-0 z-99">
|
||||
<SettingsPanel />
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col flex-auto min-h-0 relative z-10">
|
||||
<FuseDialog />
|
||||
|
||||
<FuseSuspense>{useRoutes(routes)}</FuseSuspense>
|
||||
|
||||
{props.children}
|
||||
</div>
|
||||
|
||||
{config.footer.display && (
|
||||
<FooterLayout1 className={config.footer.style === 'fixed' && 'sticky bottom-0'} />
|
||||
)}
|
||||
</main>
|
||||
|
||||
{config.navbar.display && config.navbar.position === 'right' && <NavbarWrapperLayout1 />}
|
||||
</div>
|
||||
|
||||
{config.rightSidePanel.display && <RightSideLayout1 />}
|
||||
<FuseMessage />
|
||||
</Root>
|
||||
);
|
||||
}
|
||||
|
||||
export default memo(Layout1);
|
||||
152
src/app/theme-layouts/layout1/Layout1Config.js
Normal file
152
src/app/theme-layouts/layout1/Layout1Config.js
Normal file
@@ -0,0 +1,152 @@
|
||||
const config = {
|
||||
title: 'Layout 1 - Vertical',
|
||||
defaults: {
|
||||
mode: 'container',
|
||||
containerWidth: 1570,
|
||||
navbar: {
|
||||
display: true,
|
||||
style: 'style-1',
|
||||
folded: true,
|
||||
position: 'left',
|
||||
},
|
||||
toolbar: {
|
||||
display: true,
|
||||
style: 'fixed',
|
||||
},
|
||||
footer: {
|
||||
display: true,
|
||||
style: 'fixed',
|
||||
},
|
||||
leftSidePanel: {
|
||||
display: true,
|
||||
},
|
||||
rightSidePanel: {
|
||||
display: true,
|
||||
},
|
||||
},
|
||||
form: {
|
||||
mode: {
|
||||
title: 'Mode',
|
||||
type: 'radio',
|
||||
options: [
|
||||
{
|
||||
name: 'Boxed',
|
||||
value: 'boxed',
|
||||
},
|
||||
{
|
||||
name: 'Full Width',
|
||||
value: 'fullwidth',
|
||||
},
|
||||
{
|
||||
name: 'Container',
|
||||
value: 'container',
|
||||
},
|
||||
],
|
||||
},
|
||||
containerWidth: {
|
||||
title: 'Container Width (px)',
|
||||
type: 'number',
|
||||
},
|
||||
|
||||
navbar: {
|
||||
type: 'group',
|
||||
title: 'Navbar',
|
||||
children: {
|
||||
display: {
|
||||
title: 'Display',
|
||||
type: 'switch',
|
||||
},
|
||||
position: {
|
||||
title: 'Position',
|
||||
type: 'radio',
|
||||
options: [
|
||||
{
|
||||
name: 'Left',
|
||||
value: 'left',
|
||||
},
|
||||
{
|
||||
name: 'Right',
|
||||
value: 'right',
|
||||
},
|
||||
],
|
||||
},
|
||||
style: {
|
||||
title: 'Style',
|
||||
type: 'radio',
|
||||
options: [
|
||||
{
|
||||
name: 'Slide (style-1)',
|
||||
value: 'style-1',
|
||||
},
|
||||
{
|
||||
name: 'Folded (style-2)',
|
||||
value: 'style-2',
|
||||
},
|
||||
{
|
||||
name: 'Tabbed (style-3)',
|
||||
value: 'style-3',
|
||||
},
|
||||
{
|
||||
name: 'Tabbed Dense (style-3-dense)',
|
||||
value: 'style-3-dense',
|
||||
},
|
||||
],
|
||||
},
|
||||
folded: {
|
||||
title: 'Folded (style-2, style-3)',
|
||||
type: 'switch',
|
||||
},
|
||||
},
|
||||
},
|
||||
toolbar: {
|
||||
type: 'group',
|
||||
title: 'Toolbar',
|
||||
children: {
|
||||
display: {
|
||||
title: 'Display',
|
||||
type: 'switch',
|
||||
},
|
||||
style: {
|
||||
title: 'Style',
|
||||
type: 'radio',
|
||||
options: [
|
||||
{
|
||||
name: 'Fixed',
|
||||
value: 'fixed',
|
||||
},
|
||||
{
|
||||
name: 'Static',
|
||||
value: 'static',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
footer: {
|
||||
type: 'group',
|
||||
title: 'Footer',
|
||||
children: {
|
||||
display: {
|
||||
title: 'Display',
|
||||
type: 'switch',
|
||||
},
|
||||
style: {
|
||||
title: 'Style',
|
||||
type: 'radio',
|
||||
options: [
|
||||
{
|
||||
name: 'Fixed',
|
||||
value: 'fixed',
|
||||
},
|
||||
{
|
||||
name: 'Static',
|
||||
value: 'static',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
33
src/app/theme-layouts/layout1/components/FooterLayout1.js
Normal file
33
src/app/theme-layouts/layout1/components/FooterLayout1.js
Normal file
@@ -0,0 +1,33 @@
|
||||
import AppBar from '@mui/material/AppBar';
|
||||
import { ThemeProvider } from '@mui/material/styles';
|
||||
import Toolbar from '@mui/material/Toolbar';
|
||||
import { memo } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { selectFooterTheme } from 'app/store/fuse/settingsSlice';
|
||||
import clsx from 'clsx';
|
||||
|
||||
function FooterLayout1(props) {
|
||||
const footerTheme = useSelector(selectFooterTheme);
|
||||
|
||||
return (
|
||||
<ThemeProvider theme={footerTheme}>
|
||||
<AppBar
|
||||
id="fuse-footer"
|
||||
className={clsx('relative z-20 shadow-md', props.className)}
|
||||
color="default"
|
||||
sx={{
|
||||
backgroundColor: (theme) =>
|
||||
theme.palette.mode === 'light'
|
||||
? footerTheme.palette.background.paper
|
||||
: footerTheme.palette.background.default,
|
||||
}}
|
||||
>
|
||||
<Toolbar className="min-h-48 md:min-h-64 px-8 sm:px-12 py-0 flex items-center overflow-x-auto">
|
||||
Footer
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
|
||||
export default memo(FooterLayout1);
|
||||
@@ -0,0 +1,7 @@
|
||||
import { memo } from 'react';
|
||||
|
||||
function LeftSideLayout1() {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
export default memo(LeftSideLayout1);
|
||||
@@ -0,0 +1,33 @@
|
||||
import { ThemeProvider } from '@mui/material/styles';
|
||||
import { memo } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { selectFuseCurrentLayoutConfig, selectNavbarTheme } from 'app/store/fuse/settingsSlice';
|
||||
import { selectFuseNavbar } from 'app/store/fuse/navbarSlice';
|
||||
import NavbarStyle1 from './navbar/style-1/NavbarStyle1';
|
||||
import NavbarStyle2 from './navbar/style-2/NavbarStyle2';
|
||||
import NavbarStyle3 from './navbar/style-3/NavbarStyle3';
|
||||
import NavbarToggleFab from '../../shared-components/NavbarToggleFab';
|
||||
|
||||
function NavbarWrapperLayout1(props) {
|
||||
const config = useSelector(selectFuseCurrentLayoutConfig);
|
||||
const navbar = useSelector(selectFuseNavbar);
|
||||
|
||||
const navbarTheme = useSelector(selectNavbarTheme);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ThemeProvider theme={navbarTheme}>
|
||||
<>
|
||||
{config.navbar.style === 'style-1' && <NavbarStyle1 />}
|
||||
{config.navbar.style === 'style-2' && <NavbarStyle2 />}
|
||||
{config.navbar.style === 'style-3' && <NavbarStyle3 />}
|
||||
{config.navbar.style === 'style-3-dense' && <NavbarStyle3 dense />}
|
||||
</>
|
||||
</ThemeProvider>
|
||||
|
||||
{config.navbar.display && !config.toolbar.display && !navbar.open && <NavbarToggleFab />}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default memo(NavbarWrapperLayout1);
|
||||
15
src/app/theme-layouts/layout1/components/RightSideLayout1.js
Normal file
15
src/app/theme-layouts/layout1/components/RightSideLayout1.js
Normal file
@@ -0,0 +1,15 @@
|
||||
import { memo } from 'react';
|
||||
import QuickPanel from '../../shared-components/quickPanel/QuickPanel';
|
||||
import NotificationPanel from '../../shared-components/notificationPanel/NotificationPanel';
|
||||
|
||||
function RightSideLayout1(props) {
|
||||
return (
|
||||
<>
|
||||
<QuickPanel />
|
||||
|
||||
<NotificationPanel />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default memo(RightSideLayout1);
|
||||
103
src/app/theme-layouts/layout1/components/ToolbarLayout1.js
Normal file
103
src/app/theme-layouts/layout1/components/ToolbarLayout1.js
Normal file
@@ -0,0 +1,103 @@
|
||||
import { ThemeProvider } from '@mui/material/styles';
|
||||
import AppBar from '@mui/material/AppBar';
|
||||
import Hidden from '@mui/material/Hidden';
|
||||
import Toolbar from '@mui/material/Toolbar';
|
||||
import clsx from 'clsx';
|
||||
import { memo } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { selectFuseCurrentLayoutConfig, selectToolbarTheme } from 'app/store/fuse/settingsSlice';
|
||||
import { selectFuseNavbar } from 'app/store/fuse/navbarSlice';
|
||||
import AdjustFontSize from '../../shared-components/AdjustFontSize';
|
||||
import FullScreenToggle from '../../shared-components/FullScreenToggle';
|
||||
import LanguageSwitcher from '../../shared-components/LanguageSwitcher';
|
||||
import NotificationPanelToggleButton from '../../shared-components/notificationPanel/NotificationPanelToggleButton';
|
||||
import NavigationShortcuts from '../../shared-components/NavigationShortcuts';
|
||||
import NavigationSearch from '../../shared-components/NavigationSearch';
|
||||
import NavbarToggleButton from '../../shared-components/NavbarToggleButton';
|
||||
import UserMenu from '../../shared-components/UserMenu';
|
||||
import QuickPanelToggleButton from '../../shared-components/quickPanel/QuickPanelToggleButton';
|
||||
import ChatPanelToggleButton from '../../shared-components/chatPanel/ChatPanelToggleButton';
|
||||
|
||||
function ToolbarLayout1(props) {
|
||||
const config = useSelector(selectFuseCurrentLayoutConfig);
|
||||
const navbar = useSelector(selectFuseNavbar);
|
||||
const toolbarTheme = useSelector(selectToolbarTheme);
|
||||
|
||||
return (
|
||||
<ThemeProvider theme={toolbarTheme}>
|
||||
<AppBar
|
||||
id="fuse-toolbar"
|
||||
className={clsx('flex relative z-20 shadow-md', props.className)}
|
||||
color="default"
|
||||
sx={{
|
||||
backgroundColor: (theme) =>
|
||||
theme.palette.mode === 'light'
|
||||
? toolbarTheme.palette.background.paper
|
||||
: toolbarTheme.palette.background.default,
|
||||
}}
|
||||
position="static"
|
||||
>
|
||||
<Toolbar className="p-0 min-h-48 md:min-h-64">
|
||||
<div className="flex flex-1 px-16">
|
||||
{config.navbar.display && config.navbar.position === 'left' && (
|
||||
<>
|
||||
<Hidden lgDown>
|
||||
{(config.navbar.style === 'style-3' ||
|
||||
config.navbar.style === 'style-3-dense') && (
|
||||
<NavbarToggleButton className="w-40 h-40 p-0 mx-0" />
|
||||
)}
|
||||
|
||||
{config.navbar.style === 'style-1' && !navbar.open && (
|
||||
<NavbarToggleButton className="w-40 h-40 p-0 mx-0" />
|
||||
)}
|
||||
</Hidden>
|
||||
|
||||
<Hidden lgUp>
|
||||
<NavbarToggleButton className="w-40 h-40 p-0 mx-0 sm:mx-8" />
|
||||
</Hidden>
|
||||
</>
|
||||
)}
|
||||
|
||||
<Hidden lgDown>
|
||||
<NavigationShortcuts />
|
||||
</Hidden>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center px-8 h-full overflow-x-auto">
|
||||
<LanguageSwitcher />
|
||||
|
||||
<AdjustFontSize />
|
||||
|
||||
<FullScreenToggle />
|
||||
|
||||
<NavigationSearch />
|
||||
|
||||
<Hidden lgUp>
|
||||
<ChatPanelToggleButton />
|
||||
</Hidden>
|
||||
|
||||
<QuickPanelToggleButton />
|
||||
|
||||
<NotificationPanelToggleButton />
|
||||
|
||||
<UserMenu />
|
||||
</div>
|
||||
|
||||
{config.navbar.display && config.navbar.position === 'right' && (
|
||||
<>
|
||||
<Hidden lgDown>
|
||||
{!navbar.open && <NavbarToggleButton className="w-40 h-40 p-0 mx-0" />}
|
||||
</Hidden>
|
||||
|
||||
<Hidden lgUp>
|
||||
<NavbarToggleButton className="w-40 h-40 p-0 mx-0 sm:mx-8" />
|
||||
</Hidden>
|
||||
</>
|
||||
)}
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
|
||||
export default memo(ToolbarLayout1);
|
||||
@@ -0,0 +1,82 @@
|
||||
import Hidden from '@mui/material/Hidden';
|
||||
import { styled } from '@mui/material/styles';
|
||||
import SwipeableDrawer from '@mui/material/SwipeableDrawer';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { navbarCloseMobile, selectFuseNavbar } from 'app/store/fuse/navbarSlice';
|
||||
import { selectFuseCurrentLayoutConfig } from 'app/store/fuse/settingsSlice';
|
||||
import NavbarStyle1Content from './NavbarStyle1Content';
|
||||
|
||||
const navbarWidth = 280;
|
||||
|
||||
const StyledNavBar = styled('div')(({ theme, open, position }) => ({
|
||||
minWidth: navbarWidth,
|
||||
width: navbarWidth,
|
||||
maxWidth: navbarWidth,
|
||||
...(!open && {
|
||||
transition: theme.transitions.create('margin', {
|
||||
easing: theme.transitions.easing.easeOut,
|
||||
duration: theme.transitions.duration.leavingScreen,
|
||||
}),
|
||||
...(position === 'left' && {
|
||||
marginLeft: `-${navbarWidth}px`,
|
||||
}),
|
||||
...(position === 'right' && {
|
||||
marginRight: `-${navbarWidth}px`,
|
||||
}),
|
||||
}),
|
||||
...(open && {
|
||||
transition: theme.transitions.create('margin', {
|
||||
easing: theme.transitions.easing.easeOut,
|
||||
duration: theme.transitions.duration.enteringScreen,
|
||||
}),
|
||||
}),
|
||||
}));
|
||||
|
||||
const StyledNavBarMobile = styled(SwipeableDrawer)(({ theme }) => ({
|
||||
'& .MuiDrawer-paper': {
|
||||
minWidth: navbarWidth,
|
||||
width: navbarWidth,
|
||||
maxWidth: navbarWidth,
|
||||
},
|
||||
}));
|
||||
|
||||
function NavbarStyle1(props) {
|
||||
const dispatch = useDispatch();
|
||||
const config = useSelector(selectFuseCurrentLayoutConfig);
|
||||
const navbar = useSelector(selectFuseNavbar);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Hidden lgDown>
|
||||
<StyledNavBar
|
||||
className="flex-col flex-auto sticky top-0 overflow-hidden h-screen shrink-0 z-20 shadow-5"
|
||||
open={navbar.open}
|
||||
position={config.navbar.position}
|
||||
>
|
||||
<NavbarStyle1Content />
|
||||
</StyledNavBar>
|
||||
</Hidden>
|
||||
|
||||
<Hidden lgUp>
|
||||
<StyledNavBarMobile
|
||||
classes={{
|
||||
paper: 'flex-col flex-auto h-full',
|
||||
}}
|
||||
anchor={config.navbar.position}
|
||||
variant="temporary"
|
||||
open={navbar.mobileOpen}
|
||||
onClose={() => dispatch(navbarCloseMobile())}
|
||||
onOpen={() => {}}
|
||||
disableSwipeToOpen
|
||||
ModalProps={{
|
||||
keepMounted: true, // Better open performance on mobile.
|
||||
}}
|
||||
>
|
||||
<NavbarStyle1Content />
|
||||
</StyledNavBarMobile>
|
||||
</Hidden>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default NavbarStyle1;
|
||||
@@ -0,0 +1,62 @@
|
||||
import FuseScrollbars from '@fuse/core/FuseScrollbars';
|
||||
import { styled } from '@mui/material/styles';
|
||||
import clsx from 'clsx';
|
||||
import { memo } from 'react';
|
||||
import Logo from '../../../../shared-components/Logo';
|
||||
import NavbarToggleButton from '../../../../shared-components/NavbarToggleButton';
|
||||
import UserNavbarHeader from '../../../../shared-components/UserNavbarHeader';
|
||||
import Navigation from '../../../../shared-components/Navigation';
|
||||
|
||||
const Root = styled('div')(({ theme }) => ({
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
'& ::-webkit-scrollbar-thumb': {
|
||||
boxShadow: `inset 0 0 0 20px ${
|
||||
theme.palette.mode === 'light' ? 'rgba(0, 0, 0, 0.24)' : 'rgba(255, 255, 255, 0.24)'
|
||||
}`,
|
||||
},
|
||||
'& ::-webkit-scrollbar-thumb:active': {
|
||||
boxShadow: `inset 0 0 0 20px ${
|
||||
theme.palette.mode === 'light' ? 'rgba(0, 0, 0, 0.37)' : 'rgba(255, 255, 255, 0.37)'
|
||||
}`,
|
||||
},
|
||||
}));
|
||||
|
||||
const StyledContent = styled(FuseScrollbars)(({ theme }) => ({
|
||||
overscrollBehavior: 'contain',
|
||||
overflowX: 'hidden',
|
||||
overflowY: 'auto',
|
||||
WebkitOverflowScrolling: 'touch',
|
||||
backgroundRepeat: 'no-repeat',
|
||||
backgroundSize: '100% 40px, 100% 10px',
|
||||
backgroundAttachment: 'local, scroll',
|
||||
}));
|
||||
|
||||
function NavbarStyle1Content(props) {
|
||||
return (
|
||||
<Root className={clsx('flex flex-auto flex-col overflow-hidden h-full', props.className)}>
|
||||
<div className="flex flex-row items-center shrink-0 h-48 md:h-72 px-20">
|
||||
<div className="flex flex-1 mx-4">
|
||||
<Logo />
|
||||
</div>
|
||||
|
||||
<NavbarToggleButton className="w-40 h-40 p-0" />
|
||||
</div>
|
||||
|
||||
<StyledContent
|
||||
className="flex flex-1 flex-col min-h-0"
|
||||
option={{ suppressScrollX: true, wheelPropagation: false }}
|
||||
>
|
||||
<UserNavbarHeader />
|
||||
|
||||
<Navigation layout="vertical" />
|
||||
|
||||
<div className="flex flex-0 items-center justify-center py-48 opacity-10">
|
||||
<img className="w-full max-w-64" src="assets/images/logo/logo.svg" alt="footer logo" />
|
||||
</div>
|
||||
</StyledContent>
|
||||
</Root>
|
||||
);
|
||||
}
|
||||
|
||||
export default memo(NavbarStyle1Content);
|
||||
@@ -0,0 +1,171 @@
|
||||
import Hidden from '@mui/material/Hidden';
|
||||
import { styled } from '@mui/material/styles';
|
||||
import SwipeableDrawer from '@mui/material/SwipeableDrawer';
|
||||
import {
|
||||
navbarCloseFolded,
|
||||
navbarCloseMobile,
|
||||
navbarOpenFolded,
|
||||
selectFuseNavbar,
|
||||
} from 'app/store/fuse/navbarSlice';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { selectFuseCurrentLayoutConfig } from 'app/store/fuse/settingsSlice';
|
||||
import NavbarStyle2Content from './NavbarStyle2Content';
|
||||
|
||||
const navbarWidth = 280;
|
||||
|
||||
const Root = styled('div')(({ theme, folded }) => ({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
zIndex: 4,
|
||||
[theme.breakpoints.up('lg')]: {
|
||||
width: navbarWidth,
|
||||
minWidth: navbarWidth,
|
||||
},
|
||||
|
||||
...(folded && {
|
||||
[theme.breakpoints.up('lg')]: {
|
||||
width: 76,
|
||||
minWidth: 76,
|
||||
},
|
||||
}),
|
||||
}));
|
||||
|
||||
const StyledNavbar = styled('div')(
|
||||
({ theme, position, folded, foldedandopened, foldedandclosed }) => ({
|
||||
minWidth: navbarWidth,
|
||||
width: navbarWidth,
|
||||
maxWidth: navbarWidth,
|
||||
maxHeight: '100%',
|
||||
transition: theme.transitions.create(['width', 'min-width'], {
|
||||
easing: theme.transitions.easing.sharp,
|
||||
duration: theme.transitions.duration.shorter,
|
||||
}),
|
||||
|
||||
...(position === 'left' && {
|
||||
left: 0,
|
||||
}),
|
||||
|
||||
...(position === 'right' && {
|
||||
right: 0,
|
||||
}),
|
||||
|
||||
...(folded && {
|
||||
position: 'absolute',
|
||||
width: 76,
|
||||
minWidth: 76,
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
}),
|
||||
|
||||
...(foldedandopened && {
|
||||
width: navbarWidth,
|
||||
minWidth: navbarWidth,
|
||||
}),
|
||||
|
||||
...(foldedandclosed && {
|
||||
'& .NavbarStyle2-content': {
|
||||
'& .logo-icon': {
|
||||
width: 44,
|
||||
height: 44,
|
||||
},
|
||||
'& .logo-text': {
|
||||
opacity: 0,
|
||||
},
|
||||
'& .react-badge': {
|
||||
opacity: 0,
|
||||
},
|
||||
'& .fuse-list-item': {
|
||||
width: 56,
|
||||
},
|
||||
'& .fuse-list-item-text, & .arrow-icon, & .item-badge': {
|
||||
opacity: 0,
|
||||
},
|
||||
'& .fuse-list-subheader .fuse-list-subheader-text': {
|
||||
opacity: 0,
|
||||
},
|
||||
'& .fuse-list-subheader:before': {
|
||||
content: '""',
|
||||
display: 'block',
|
||||
position: 'absolute',
|
||||
minWidth: 16,
|
||||
borderTop: '2px solid',
|
||||
opacity: 0.2,
|
||||
},
|
||||
'& .collapse-children': {
|
||||
display: 'none',
|
||||
},
|
||||
},
|
||||
}),
|
||||
})
|
||||
);
|
||||
|
||||
const StyledNavbarMobile = styled(SwipeableDrawer)(({ theme, position }) => ({
|
||||
'& > .MuiDrawer-paper': {
|
||||
minWidth: navbarWidth,
|
||||
width: navbarWidth,
|
||||
maxWidth: navbarWidth,
|
||||
maxHeight: '100%',
|
||||
transition: theme.transitions.create(['width', 'min-width'], {
|
||||
easing: theme.transitions.easing.sharp,
|
||||
duration: theme.transitions.duration.shorter,
|
||||
}),
|
||||
},
|
||||
}));
|
||||
|
||||
function NavbarStyle2(props) {
|
||||
const dispatch = useDispatch();
|
||||
const config = useSelector(selectFuseCurrentLayoutConfig);
|
||||
const navbar = useSelector(selectFuseNavbar);
|
||||
|
||||
// const folded = !navbar.open;
|
||||
const { folded } = config.navbar;
|
||||
const foldedandclosed = folded && !navbar.foldedOpen;
|
||||
const foldedandopened = folded && navbar.foldedOpen;
|
||||
|
||||
return (
|
||||
<Root
|
||||
folded={folded ? 1 : 0}
|
||||
open={navbar.open}
|
||||
id="fuse-navbar"
|
||||
className="sticky top-0 h-screen shrink-0 z-20 shadow-5"
|
||||
>
|
||||
<Hidden lgDown>
|
||||
<StyledNavbar
|
||||
className="flex-col flex-auto"
|
||||
position={config.navbar.position}
|
||||
folded={folded ? 1 : 0}
|
||||
foldedandopened={foldedandopened ? 1 : 0}
|
||||
foldedandclosed={foldedandclosed ? 1 : 0}
|
||||
onMouseEnter={() => foldedandclosed && dispatch(navbarOpenFolded())}
|
||||
onMouseLeave={() => foldedandopened && dispatch(navbarCloseFolded())}
|
||||
>
|
||||
<NavbarStyle2Content className="NavbarStyle2-content" />
|
||||
</StyledNavbar>
|
||||
</Hidden>
|
||||
|
||||
<Hidden lgUp>
|
||||
<StyledNavbarMobile
|
||||
classes={{
|
||||
paper: 'flex-col flex-auto h-full',
|
||||
}}
|
||||
folded={folded ? 1 : 0}
|
||||
foldedandopened={foldedandopened ? 1 : 0}
|
||||
foldedandclosed={foldedandclosed ? 1 : 0}
|
||||
anchor={config.navbar.position}
|
||||
variant="temporary"
|
||||
open={navbar.mobileOpen}
|
||||
onClose={() => dispatch(navbarCloseMobile())}
|
||||
onOpen={() => {}}
|
||||
disableSwipeToOpen
|
||||
ModalProps={{
|
||||
keepMounted: true, // Better open performance on mobile.
|
||||
}}
|
||||
>
|
||||
<NavbarStyle2Content className="NavbarStyle2-content" />
|
||||
</StyledNavbarMobile>
|
||||
</Hidden>
|
||||
</Root>
|
||||
);
|
||||
}
|
||||
|
||||
export default NavbarStyle2;
|
||||
@@ -0,0 +1,54 @@
|
||||
import FuseScrollbars from '@fuse/core/FuseScrollbars';
|
||||
import { styled } from '@mui/material/styles';
|
||||
import clsx from 'clsx';
|
||||
import { memo } from 'react';
|
||||
import Logo from '../../../../shared-components/Logo';
|
||||
import NavbarToggleButton from '../../../../shared-components/NavbarToggleButton';
|
||||
import Navigation from '../../../../shared-components/Navigation';
|
||||
|
||||
const Root = styled('div')(({ theme }) => ({
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
'& ::-webkit-scrollbar-thumb': {
|
||||
boxShadow: `inset 0 0 0 20px ${
|
||||
theme.palette.mode === 'light' ? 'rgba(0, 0, 0, 0.24)' : 'rgba(255, 255, 255, 0.24)'
|
||||
}`,
|
||||
},
|
||||
'& ::-webkit-scrollbar-thumb:active': {
|
||||
boxShadow: `inset 0 0 0 20px ${
|
||||
theme.palette.mode === 'light' ? 'rgba(0, 0, 0, 0.37)' : 'rgba(255, 255, 255, 0.37)'
|
||||
}`,
|
||||
},
|
||||
}));
|
||||
|
||||
const StyledContent = styled(FuseScrollbars)(({ theme }) => ({
|
||||
overscrollBehavior: 'contain',
|
||||
overflowX: 'hidden',
|
||||
overflowY: 'auto',
|
||||
WebkitOverflowScrolling: 'touch',
|
||||
background:
|
||||
'linear-gradient(rgba(0, 0, 0, 0) 30%, rgba(0, 0, 0, 0) 30%), linear-gradient(rgba(0, 0, 0, 0.25) 0, rgba(0, 0, 0, 0) 40%)',
|
||||
backgroundRepeat: 'no-repeat',
|
||||
backgroundSize: '100% 40px, 100% 10px',
|
||||
backgroundAttachment: 'local, scroll',
|
||||
}));
|
||||
|
||||
function NavbarStyle2Content(props) {
|
||||
return (
|
||||
<Root className={clsx('flex flex-auto flex-col overflow-hidden h-full', props.className)}>
|
||||
<div className="flex flex-row items-center shrink-0 h-48 md:h-76 px-12">
|
||||
<div className="flex flex-1 mx-4">
|
||||
<Logo />
|
||||
</div>
|
||||
|
||||
<NavbarToggleButton className="w-40 h-40 p-0" />
|
||||
</div>
|
||||
|
||||
<StyledContent option={{ suppressScrollX: true, wheelPropagation: false }}>
|
||||
<Navigation layout="vertical" />
|
||||
</StyledContent>
|
||||
</Root>
|
||||
);
|
||||
}
|
||||
|
||||
export default memo(NavbarStyle2Content);
|
||||
@@ -0,0 +1,149 @@
|
||||
import Hidden from '@mui/material/Hidden';
|
||||
import { styled } from '@mui/material/styles';
|
||||
import SwipeableDrawer from '@mui/material/SwipeableDrawer';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { navbarCloseMobile, selectFuseNavbar } from 'app/store/fuse/navbarSlice';
|
||||
import GlobalStyles from '@mui/material/GlobalStyles';
|
||||
import { selectFuseCurrentLayoutConfig } from 'app/store/fuse/settingsSlice';
|
||||
import NavbarStyle3Content from './NavbarStyle3Content';
|
||||
|
||||
const navbarWidth = 120;
|
||||
const navbarWidthDense = 64;
|
||||
const panelWidth = 280;
|
||||
|
||||
const StyledNavBar = styled('div')(({ theme, dense, open, folded, position }) => ({
|
||||
minWidth: navbarWidth,
|
||||
width: navbarWidth,
|
||||
maxWidth: navbarWidth,
|
||||
|
||||
...(dense && {
|
||||
minWidth: navbarWidthDense,
|
||||
width: navbarWidthDense,
|
||||
maxWidth: navbarWidthDense,
|
||||
|
||||
...(!open && {
|
||||
...(position === 'left' && {
|
||||
marginLeft: -navbarWidthDense,
|
||||
}),
|
||||
|
||||
...(position === 'right' && {
|
||||
marginRight: -navbarWidthDense,
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
|
||||
...(!folded && {
|
||||
minWidth: dense ? navbarWidthDense + panelWidth : navbarWidth + panelWidth,
|
||||
width: dense ? navbarWidthDense + panelWidth : navbarWidth + panelWidth,
|
||||
maxWidth: dense ? navbarWidthDense + panelWidth : navbarWidth + panelWidth,
|
||||
|
||||
'& #fuse-navbar-panel': {
|
||||
opacity: '1!important',
|
||||
pointerEvents: 'initial!important',
|
||||
},
|
||||
|
||||
...(!open && {
|
||||
...(position === 'left' && {
|
||||
marginLeft: -(dense ? navbarWidthDense + panelWidth : navbarWidth + panelWidth),
|
||||
}),
|
||||
|
||||
...(position === 'right' && {
|
||||
marginRight: -(dense ? navbarWidthDense + panelWidth : navbarWidth + panelWidth),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
|
||||
...(!open && {
|
||||
transition: theme.transitions.create('margin', {
|
||||
easing: theme.transitions.easing.easeOut,
|
||||
duration: theme.transitions.duration.leavingScreen,
|
||||
}),
|
||||
...(position === 'left' && {
|
||||
marginLeft: -(dense ? navbarWidthDense : navbarWidth),
|
||||
}),
|
||||
|
||||
...(position === 'right' && {
|
||||
marginRight: -(dense ? navbarWidthDense : navbarWidth),
|
||||
}),
|
||||
}),
|
||||
|
||||
...(open && {
|
||||
transition: theme.transitions.create('margin', {
|
||||
easing: theme.transitions.easing.easeOut,
|
||||
duration: theme.transitions.duration.enteringScreen,
|
||||
}),
|
||||
}),
|
||||
}));
|
||||
|
||||
const StyledNavBarMobile = styled(SwipeableDrawer)(({ theme }) => ({
|
||||
'& .MuiDrawer-paper': {
|
||||
'& #fuse-navbar-side-panel': {
|
||||
minWidth: 'auto',
|
||||
wdith: 'auto',
|
||||
},
|
||||
'& #fuse-navbar-panel': {
|
||||
opacity: '1!important',
|
||||
pointerEvents: 'initial!important',
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
function NavbarStyle3(props) {
|
||||
const dispatch = useDispatch();
|
||||
const config = useSelector(selectFuseCurrentLayoutConfig);
|
||||
const navbar = useSelector(selectFuseNavbar);
|
||||
const { folded } = config.navbar;
|
||||
|
||||
return (
|
||||
<>
|
||||
<GlobalStyles
|
||||
styles={(theme) => ({
|
||||
'& #fuse-navbar-side-panel': {
|
||||
width: props.dense ? navbarWidthDense : navbarWidth,
|
||||
minWidth: props.dense ? navbarWidthDense : navbarWidth,
|
||||
maxWidth: props.dense ? navbarWidthDense : navbarWidth,
|
||||
},
|
||||
'& #fuse-navbar-panel': {
|
||||
maxWidth: '100%',
|
||||
width: panelWidth,
|
||||
[theme.breakpoints.up('lg')]: {
|
||||
minWidth: panelWidth,
|
||||
maxWidth: 'initial',
|
||||
},
|
||||
},
|
||||
})}
|
||||
/>
|
||||
<Hidden lgDown>
|
||||
<StyledNavBar
|
||||
open={navbar.open}
|
||||
dense={props.dense ? 1 : 0}
|
||||
folded={folded ? 1 : 0}
|
||||
position={config.navbar.position}
|
||||
className="flex-col flex-auto sticky top-0 h-screen shrink-0 z-20 shadow-5"
|
||||
>
|
||||
<NavbarStyle3Content dense={props.dense ? 1 : 0} folded={folded ? 1 : 0} />
|
||||
</StyledNavBar>
|
||||
</Hidden>
|
||||
<Hidden lgUp>
|
||||
<StyledNavBarMobile
|
||||
classes={{
|
||||
paper: 'flex-col flex-auto h-screen max-w-full w-auto overflow-hidden',
|
||||
}}
|
||||
anchor={config.navbar.position}
|
||||
variant="temporary"
|
||||
open={navbar.mobileOpen}
|
||||
onClose={() => dispatch(navbarCloseMobile())}
|
||||
onOpen={() => {}}
|
||||
disableSwipeToOpen
|
||||
ModalProps={{
|
||||
keepMounted: true, // Better open performance on mobile.
|
||||
}}
|
||||
>
|
||||
<NavbarStyle3Content dense={props.dense ? 1 : 0} folded={folded ? 1 : 0} />
|
||||
</StyledNavBarMobile>
|
||||
</Hidden>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default NavbarStyle3;
|
||||
@@ -0,0 +1,147 @@
|
||||
import FuseScrollbars from '@fuse/core/FuseScrollbars';
|
||||
import { styled, useTheme } from '@mui/material/styles';
|
||||
import ClickAwayListener from '@mui/material/ClickAwayListener';
|
||||
import clsx from 'clsx';
|
||||
import { memo, useEffect, useState } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import FuseNavigation from '@fuse/core/FuseNavigation';
|
||||
import { navbarCloseMobile } from 'app/store/fuse/navbarSlice';
|
||||
import { selectContrastMainTheme } from 'app/store/fuse/settingsSlice';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import useThemeMediaQuery from '@fuse/hooks/useThemeMediaQuery';
|
||||
import { selectNavigation } from 'app/store/fuse/navigationSlice';
|
||||
|
||||
const Root = styled('div')(({ theme }) => ({
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
}));
|
||||
|
||||
const StyledPanel = styled(FuseScrollbars)(({ theme, opened }) => ({
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
transition: theme.transitions.create(['opacity'], {
|
||||
easing: theme.transitions.easing.sharp,
|
||||
duration: theme.transitions.duration.shortest,
|
||||
}),
|
||||
opacity: 0,
|
||||
pointerEvents: 'none',
|
||||
...(opened && {
|
||||
opacity: 1,
|
||||
pointerEvents: 'initial',
|
||||
}),
|
||||
}));
|
||||
|
||||
function needsToBeOpened(location, item) {
|
||||
return location && isUrlInChildren(item, location.pathname);
|
||||
}
|
||||
|
||||
function isUrlInChildren(parent, url) {
|
||||
if (!parent.children) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < parent.children.length; i += 1) {
|
||||
if (parent.children[i].children) {
|
||||
if (isUrlInChildren(parent.children[i], url)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (parent.children[i].url === url || url.includes(parent.children[i].url)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function NavbarStyle3Content(props) {
|
||||
const isMobile = useThemeMediaQuery((theme) => theme.breakpoints.down('lg'));
|
||||
const navigation = useSelector(selectNavigation);
|
||||
const [selectedNavigation, setSelectedNavigation] = useState([]);
|
||||
const [panelOpen, setPanelOpen] = useState(false);
|
||||
const theme = useTheme();
|
||||
const dispatch = useDispatch();
|
||||
const contrastTheme = useSelector(selectContrastMainTheme(theme.palette.primary.main));
|
||||
const location = useLocation();
|
||||
|
||||
useEffect(() => {
|
||||
navigation?.forEach((item) => {
|
||||
if (needsToBeOpened(location, item)) {
|
||||
setSelectedNavigation([item]);
|
||||
}
|
||||
});
|
||||
}, [navigation, location]);
|
||||
|
||||
function handleParentItemClick(selected) {
|
||||
/** if there is no child item do not set/open panel
|
||||
*/
|
||||
if (!selected.children) {
|
||||
setSelectedNavigation([]);
|
||||
setPanelOpen(false);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* If navigation already selected toggle panel visibility
|
||||
*/
|
||||
if (selectedNavigation[0]?.id === selected.id) {
|
||||
setPanelOpen(!panelOpen);
|
||||
} else {
|
||||
/**
|
||||
* Set navigation and open panel
|
||||
*/
|
||||
setSelectedNavigation([selected]);
|
||||
setPanelOpen(true);
|
||||
}
|
||||
}
|
||||
|
||||
function handleChildItemClick(selected) {
|
||||
setPanelOpen(false);
|
||||
if (isMobile) {
|
||||
dispatch(navbarCloseMobile());
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<ClickAwayListener onClickAway={() => setPanelOpen(false)}>
|
||||
<Root className={clsx('flex flex-auto flex h-full', props.className)}>
|
||||
<div id="fuse-navbar-side-panel" className="flex shrink-0 flex-col items-center">
|
||||
<img className="w-44 my-32" src="assets/images/logo/logo.svg" alt="logo" />
|
||||
|
||||
<FuseScrollbars
|
||||
className="flex flex-1 min-h-0 justify-center w-full overflow-y-auto overflow-x-hidden"
|
||||
option={{ suppressScrollX: true, wheelPropagation: false }}
|
||||
>
|
||||
<FuseNavigation
|
||||
className={clsx('navigation')}
|
||||
navigation={navigation}
|
||||
layout="vertical-2"
|
||||
onItemClick={handleParentItemClick}
|
||||
firstLevel
|
||||
selectedId={selectedNavigation[0]?.id}
|
||||
dense={props.dense}
|
||||
/>
|
||||
</FuseScrollbars>
|
||||
</div>
|
||||
|
||||
{selectedNavigation.length > 0 && (
|
||||
<StyledPanel
|
||||
id="fuse-navbar-panel"
|
||||
opened={panelOpen}
|
||||
className={clsx('shadow-5 overflow-y-auto overflow-x-hidden')}
|
||||
option={{ suppressScrollX: true, wheelPropagation: false }}
|
||||
>
|
||||
<FuseNavigation
|
||||
className={clsx('navigation')}
|
||||
navigation={selectedNavigation}
|
||||
layout="vertical"
|
||||
onItemClick={handleChildItemClick}
|
||||
/>
|
||||
</StyledPanel>
|
||||
)}
|
||||
</Root>
|
||||
</ClickAwayListener>
|
||||
);
|
||||
}
|
||||
|
||||
export default memo(NavbarStyle3Content);
|
||||
Reference in New Issue
Block a user