Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure Login page is customizable through MUI theme #6762

Merged
merged 1 commit into from
Nov 9, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;