Skip to content

Commit

Permalink
Merge pull request #6762 from marmelab/fix-login-theming
Browse files Browse the repository at this point in the history
Ensure Login page is customizable through MUI theme
  • Loading branch information
fzaninotto committed Nov 9, 2021
2 parents ac99133 + 965b7d4 commit 7adeaf1
Showing 1 changed file with 65 additions and 56 deletions.
121 changes: 65 additions & 56 deletions packages/ra-ui-materialui/src/auth/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,52 @@ import { createMuiTheme } from '../layout';
import DefaultNotification from '../layout/Notification';
import DefaultLoginForm from './LoginForm';

/**
* A standalone login page, to serve as authentication gate to the admin
*
* Expects the user to enter a login and a password, which will be checked
* by the `authProvider.login()` method. Redirects to the root page (/)
* upon success, otherwise displays an authentication error message.
*
* Copy and adapt this component to implement your own login logic
* (e.g. to authenticate via email or facebook or anything else).
*
* @example
* import MyLoginPage from './MyLoginPage';
* const App = () => (
* <Admin loginPage={MyLoginPage} authProvider={authProvider}>
* ...
* </Admin>
* );
*/
const Login: React.FunctionComponent<LoginProps> = 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;
Expand Down Expand Up @@ -64,27 +110,8 @@ const useStyles = makeStyles(
{ name: 'RaLogin' }
);

/**
* A standalone login page, to serve as authentication gate to the admin
*
* Expects the user to enter a login and a password, which will be checked
* by the `authProvider.login()` method. Redirects to the root page (/)
* upon success, otherwise displays an authentication error message.
*
* Copy and adapt this component to implement your own login logic
* (e.g. to authenticate via email or facebook or anything else).
*
* @example
* import MyLoginPage from './MyLoginPage';
* const App = () => (
* <Admin loginPage={MyLoginPage} authProvider={authProvider}>
* ...
* </Admin>
* );
*/
const Login: React.FunctionComponent<LoginProps> = props => {
const LoginView: React.FunctionComponent<Omit<LoginProps, 'theme'>> = props => {
const {
theme,
title,
classes: classesOverride,
className,
Expand All @@ -95,9 +122,8 @@ const Login: React.FunctionComponent<LoginProps> = props => {
...rest
} = props;
const containerRef = useRef<HTMLDivElement>();

const classes = useStyles(props);
const muiTheme = useMemo(() => createMuiTheme(theme), [theme]);
let backgroundImageLoaded = false;
const checkAuth = useCheckAuth();
const history = useHistory();
useEffect(() => {
Expand All @@ -111,6 +137,8 @@ const Login: React.FunctionComponent<LoginProps> = props => {
});
}, [checkAuth, history]);

let backgroundImageLoaded = false;

const updateBackgroundImage = () => {
if (!backgroundImageLoaded && containerRef.current) {
containerRef.current.style.backgroundImage = `url(${backgroundImage})`;
Expand All @@ -134,39 +162,20 @@ const Login: React.FunctionComponent<LoginProps> = props => {
});

return (
<ThemeProvider theme={muiTheme}>
<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>
</ThemeProvider>
<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>
);
};

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;

0 comments on commit 7adeaf1

Please sign in to comment.