import React , { HtmlHTMLAttributes , ComponentType , createElement , ReactNode , useRef , useEffect , useMemo , } from 'react' ; import PropTypes from 'prop-types' ; import classnames from 'classnames' ; import { Card , Avatar , Theme } from '@material-ui/core' ; import { makeStyles } from '@material-ui/core/styles' ; import { ThemeProvider } from '@material-ui/styles' ; import LockIcon from '@material-ui/icons/Lock' ; import { StaticContext } from 'react-router' ; import { useHistory } from 'react-router-dom' ; import { useCheckAuth , TitleComponent } from 'ra-core' ; import defaultTheme from '../defaultTheme' ; import { createMuiTheme } from '../layout' ; import DefaultNotification from '../layout/Notification' ; import DefaultLoginForm from './LoginForm' ; example const Login = props => { const { theme , ... rest } = props ; const muiTheme = useMemo ( ( ) => createMuiTheme ( theme ) , [ theme ] ) ; return ( < ThemeProvider theme = { muiTheme } > < LoginView { ... rest } / > < /ThemeProvider>); } ; Login . propTypes = { backgroundImage : PropTypes . string , children : PropTypes . node , classes : PropTypes . object , className : PropTypes . string , theme : PropTypes . object , staticContext : PropTypes . object , } ; Login . defaultProps = { theme : defaultTheme , children : < DefaultLoginForm />, notification : DefaultNotification , } ; export default Login ; export interface LoginProps extends Omit < HtmlHTMLAttributes < HTMLDivElement > , 'title' > { backgroundImage ? : string ; children ? : ReactNode ; classes ? : object ; className ? : string ; notification ? : ComponentType ; staticContext ? : StaticContext ; theme ? : object ; title ? : TitleComponent ; } const useStyles = makeStyles ( ( theme ) => ( { main : { display : 'flex' , flexDirection : 'column' , minHeight : '100vh' , height : '1px' , alignItems : 'center' , justifyContent : 'flex-start' , backgroundRepeat : 'no-repeat' , backgroundSize : 'cover' , backgroundImage : 'radial-gradient(circle at 50% 14em, #313264 0%, #00023b 60%, #00023b 100%)' , } , card : { minWidth : 300 , marginTop : '6em' , } , avatar : { margin : '1em' , display : 'flex' , justifyContent : 'center' , } , icon : { backgroundColor : theme . palette . secondary [ 500 ] , } , } ) , { name : 'RaLogin' } ) ; const LoginView = props => { const { title , classes : classesOverride , className , children , notification , staticContext , backgroundImage , ... rest } = props ; const containerRef = useRef < HTMLDivElement > ( ) ; const classes = useStyles ( props ) ; const checkAuth = useCheckAuth ( ) ; const history = useHistory ( ) ; useEffect ( ( ) => { checkAuth ( { } , false ) . then ( ( ) => { history . push ( '/' ) ; } ) . catch ( ( ) => { } ) ; } , [ checkAuth , history ] ) ; let backgroundImageLoaded = false ; const updateBackgroundImage = ( ) => { if ( ! backgroundImageLoaded && containerRef . current ) { containerRef . current . style . backgroundImage = `url(${ backgroundImage })` ; backgroundImageLoaded = true ; } } ; const lazyLoadBackgroundImage = ( ) => { if ( backgroundImage ) { const img = new Image ( ) ; img . onload = updateBackgroundImage ; img . src = backgroundImage ; } } ; useEffect ( ( ) => { if ( ! backgroundImageLoaded ) { lazyLoadBackgroundImage ( ) ; } } ) ; return ( < div className = { classnames ( classes . main , className ) } { ... rest } ref = { containerRef } > < Card className = { classes . card } > < div className = { classes . avatar } > < Avatar className = { classes . icon } > < LockIcon /> < /Avatar> < /div> { children } < /Card> { notification ? createElement ( notification ) : null } < /div>); } ;