import React, { ComponentType, ErrorInfo, Suspense, useState } from "react"; import { ErrorBoundary } from "react-error-boundary"; import clsx from "clsx"; import { styled, SxProps, Theme } from "@mui/material/styles"; import { Toolbar, useMediaQuery, Stack, Box, Container } from "@mui/material"; import { AppBarClasses, StyledAppBar } from "./AppBar"; import { Loading, MenuProps, Sidebar as DefaultSidebar, SidebarToggleButton, UserMenu, Error, ErrorProps, SidebarProps, AppBarProps, } from "react-admin"; import { HorizontalMenu } from "./HorizontalMenu"; const RaLogo = () => { return ; }; const ExampleFooter = () => { return ( ({ background: theme.palette.grey[900], padding: theme.spacing(1), color: theme.palette.secondary.contrastText, })} > Footer content ); }; const DefaultUserMenu = ; export const ContainerLayout = (props: LayoutProps) => { const { appBar: AppBar = StyledAppBar, children, className, error: errorComponent, menu: Menu = HorizontalMenu, logo: Logo = RaLogo, sidebar: Sidebar = DefaultSidebar, footerContent: Footer = ExampleFooter, userMenu = DefaultUserMenu, ...rest } = props; const isXSmall = useMediaQuery((theme) => theme.breakpoints.down("sm") ); const [errorInfo, setErrorInfo] = useState(undefined); const handleError = (_error: Error, info: ErrorInfo) => { setErrorInfo(info); }; return ( ({ justifyContent: "space-between", [theme.breakpoints.down("sm")]: { justifyContent: "flex-start", }, })} > {isXSmall ? ( ) : ( )} {typeof userMenu === "boolean" ? ( userMenu === true ? ( ) : null ) : ( userMenu )} {isXSmall && ( )} ( )} > }>{children} {Footer ? : null} ); }; export interface LayoutProps { appBar?: ComponentType; logo?: ComponentType; className?: string; children: React.ReactNode; userMenu?: JSX.Element | boolean; error?: ComponentType; menu?: ComponentType; sidebar?: ComponentType; footerContent?: ComponentType | false; sx?: SxProps; } export interface LayoutState { hasError: boolean; error?: Error; errorInfo?: ErrorInfo; } const PREFIX = "RaLayout"; export const LayoutClasses = { appFrame: `${PREFIX}-appFrame`, contentWithSidebar: `${PREFIX}-contentWithSidebar`, content: `${PREFIX}-content`, }; const Core = styled("div", { name: PREFIX, overridesResolver: (_props, styles) => styles.root, })(({ theme }) => ({ display: "flex", flexDirection: "column", zIndex: 1, minHeight: "100vh", backgroundColor: theme.palette.background.default, position: "relative", width: "100%", color: theme.palette.getContrastText(theme.palette.background.default), [`& .${LayoutClasses.appFrame}`]: { display: "flex", flexDirection: "column", flexGrow: 1, marginTop: theme.spacing(6), [theme.breakpoints.down("sm")]: { marginTop: theme.spacing(7), }, }, [`& .${LayoutClasses.contentWithSidebar}`]: { display: "flex", flexGrow: 1, transition: theme.transitions.create("margin", { easing: theme.transitions.easing.easeOut, duration: theme.transitions.duration.enteringScreen, }), }, [`& .${LayoutClasses.content}`]: { backgroundColor: theme.palette.background.default, zIndex: 2, display: "flex", flexDirection: "column", flexGrow: 1, flexBasis: 0, padding: 0, [theme.breakpoints.up("xs")]: { paddingRight: theme.spacing(1), paddingLeft: theme.spacing(1), }, }, }));