import React , { useEffect } from "react" ; import { useMachine } from "@xstate/react" ; import { Interpreter } from "xstate" ; import { makeStyles , Container , Grid , useMediaQuery , useTheme } from "@material-ui/core" ; import Footer from "./Footer" ; import NavBar from "./NavBar" ; import NavDrawer from "./NavDrawer" ; import { DataContext , DataEvents } from "../machines/dataMachine" ; import { AuthMachineContext , AuthMachineEvents } from "../machines/authMachine" ; import { drawerMachine } from "../machines/drawerMachine" ; const useStyles = makeStyles ( ( theme ) => ( { root : { display : "flex" , } , toolbar : { paddingRight : 24 , } , appBarSpacer : { minHeight : theme . spacing ( 13 ) , [ theme . breakpoints . up ( "sm" ) ] : { minHeight : theme . spacing ( 14 ) , } , } , content : { flexGrow : 1 , height : "100vh" , overflow : "auto" , } , container : { minHeight : "77vh" , paddingTop : theme . spacing ( 1 ) , paddingBottom : theme . spacing ( 1 ) , [ theme . breakpoints . up ( "sm" ) ] : { paddingTop : theme . spacing ( 4 ) , padding : theme . spacing ( 4 ) , } , } , } ) ) ; interface Props { children : React . ReactNode ; authService : Interpreter < AuthMachineContext , any , AuthMachineEvents , any > ; notificationsService : Interpreter < DataContext , any , DataEvents , any > ; } const MainLayout = ( { children , notificationsService , authService } ) => { const classes = useStyles ( ) ; const theme = useTheme ( ) ; const [ drawerState , sendDrawer ] = useMachine ( drawerMachine ) ; const aboveSmallBreakpoint = useMediaQuery ( theme . breakpoints . up ( "sm" ) ) ; const xsBreakpoint = useMediaQuery ( theme . breakpoints . only ( "xs" ) ) ; const desktopDrawerOpen = drawerState ?. matches ( { desktop : "open" } ) ; const mobileDrawerOpen = drawerState ?. matches ( { mobile : "open" } ) ; const toggleDesktopDrawer = ( ) => { sendDrawer ( "TOGGLE_DESKTOP" ) ; } ; const toggleMobileDrawer = ( ) => { sendDrawer ( "TOGGLE_MOBILE" ) ; } ; const openDesktopDrawer = ( payload ) => sendDrawer ( "OPEN_DESKTOP" , payload ) ; const closeMobileDrawer = ( ) => sendDrawer ( "CLOSE_MOBILE" ) ; useEffect ( ( ) => { if ( ! desktopDrawerOpen && aboveSmallBreakpoint ) { openDesktopDrawer ( { aboveSmallBreakpoint } ) ; } } , [ aboveSmallBreakpoint , desktopDrawerOpen ] ) ; return ( < > < NavBar toggleDrawer = { xsBreakpoint ? toggleMobileDrawer : toggleDesktopDrawer } drawerOpen = { xsBreakpoint ? mobileDrawerOpen : desktopDrawerOpen } notificationsService = { notificationsService } / > < NavDrawer toggleDrawer = { xsBreakpoint ? toggleMobileDrawer : toggleDesktopDrawer } drawerOpen = { xsBreakpoint ? mobileDrawerOpen : desktopDrawerOpen } closeMobileDrawer = { closeMobileDrawer } authService = { authService } / > < main className = { classes . content } data - test = "main" > < div className = { classes . appBarSpacer } /> < Container maxWidth = "md" className = { classes . container } > < Grid container spacing = { 3 } > < Grid item xs = { 12 } > { children } < /Grid> < /Grid> < /Container> < footer > < Footer /> < /footer> < /main> < />); } ; export default MainLayout ;