import React, { useState, useRef, useEffect, useMemo } from "react";
|
import { useLocation } from 'react-router-dom';
|
import {
|
Box,
|
AppBar,
|
Card,
|
Toolbar,
|
CircularProgress,
|
Typography,
|
Tabs,
|
Tab,
|
Button
|
} from '@mui/material';
|
import {
|
Form,
|
required,
|
TextInput,
|
useTranslate,
|
useLogin,
|
useNotify,
|
SelectInput,
|
} from 'react-admin';
|
import { useForm, Controller } from 'react-hook-form';
|
import { LOGIN_BACKGROUND } from '@/config/setting';
|
import { tenants } from '@/api/auth';
|
|
const Login = () => {
|
const translate = useTranslate();
|
|
const [tab, setTab] = useState(0)
|
|
const [tenantList, setTenantList] = useState([]);
|
|
useEffect(() => {
|
tenants().then(data => {
|
setTenantList(data);
|
})
|
}, []);
|
|
return (
|
<Box
|
sx={{
|
display: 'flex',
|
flexDirection: 'column',
|
minHeight: '100vh',
|
alignItems: 'center',
|
justifyContent: 'flex-start',
|
// justifyContent: 'center',
|
background: `url(/login_bg.jpg)`, // https://unsplash.com/
|
backgroundRepeat: 'no-repeat',
|
backgroundSize: 'cover',
|
}
|
}
|
>
|
<video
|
autoPlay
|
loop
|
muted
|
style={{
|
position: 'fixed',
|
top: 0,
|
left: 0,
|
width: '100%',
|
height: '100%',
|
// objectFit: 'cover',
|
// objectFit: 'contain',
|
objectFit: 'fill',
|
// objectFit: 'scale-down',
|
zIndex: 0,
|
}}
|
>
|
{LOGIN_BACKGROUND === 'media' && (
|
<source src="/login_bg.mp4" type="video/mp4" />
|
)}
|
</video>
|
|
<Card sx={{
|
width: 400,
|
marginTop: '6em',
|
zIndex: 1
|
}}>
|
<div>
|
<AppBar position="static" sx={{ backgroundColor: '#3D4BA7' }}>
|
<Toolbar>
|
<Typography variant="h6" color="inherit">Welcome</Typography>
|
</Toolbar>
|
</AppBar>
|
</div>
|
|
<Tabs
|
value={tab}
|
onChange={(event, value) => {
|
setTab(value);
|
}}
|
indicatorColor="primary"
|
textColor="primary"
|
variant="fullWidth"
|
>
|
<Tab label="Login" sx={{ fontSize: '.8em' }} />
|
<Tab label="Register" sx={{ fontSize: '.8em' }} />
|
</Tabs>
|
|
<LoginForm
|
tab={tab}
|
tenantList={tenantList}
|
/>
|
|
<RegisterForm
|
tab={tab}
|
tenantList={tenantList}
|
/>
|
|
<Box mt={1} mb={1} sx={{ textAlign: 'center' }}>
|
<Typography variant="caption" align="center">rsf - sever</Typography>
|
</Box>
|
</Card>
|
</Box >
|
);
|
};
|
|
const LoginForm = (props) => {
|
const translate = useTranslate();
|
const notify = useNotify();
|
const login = useLogin();
|
const location = useLocation();
|
|
const { tab, tenantList } = props;
|
|
const [loading, setLoading] = useState(false);
|
const [tenantId, setTenantId] = useState(null);
|
const [username, setUsername] = useState('');
|
const [password, setPassword] = useState('');
|
const [btnDisable, setBtnDisable] = useState(true);
|
|
useEffect(() => {
|
if (tenantList.length > 0) {
|
setTenantId(tenantList[0].id);
|
}
|
setBtnDisable(!(tenantId && username && password))
|
}, [tenantList, username, password]);
|
|
const handleSubmit = (auth) => {
|
console.log(auth);
|
|
setLoading(true);
|
// js native confirm && root
|
login(
|
auth,
|
location.state ? (location.state).nextPathname : '/'
|
).catch((error) => {
|
setLoading(false);
|
notify(
|
typeof error === 'string'
|
? error
|
: typeof error === 'undefined' || !error.message
|
? 'ra.auth.sign_in_error'
|
: error.message,
|
{
|
type: 'error',
|
messageArgs: {
|
_:
|
typeof error === 'string'
|
? error
|
: error && error.message
|
? error.message
|
: undefined,
|
},
|
}
|
);
|
|
setUsername(auth.username)
|
});
|
};
|
|
return (
|
<>
|
<Form
|
onSubmit={handleSubmit}
|
noValidate
|
>
|
<Box
|
hidden={tab !== 0}
|
p={2}
|
display="flex"
|
justifyContent="center"
|
flexDirection='column'
|
>
|
<Box width="60%">
|
<SelectInput
|
label="page.login.tenant"
|
source="tenantId"
|
variant="standard"
|
choices={tenantList.map(item => ({
|
id: item.id,
|
name: item.name
|
}))}
|
validate={required()}
|
defaultValue={tenantId}
|
onChange={e => setTenantId(e.target.value)}
|
sx={{ marginTop: 0, marginBottom: 0 }}
|
/>
|
</Box>
|
|
<TextInput
|
label={translate('ra.auth.username')}
|
source="username"
|
variant="standard"
|
disabled={loading}
|
validate={required()}
|
value={username}
|
onChange={e => setUsername(e.target.value)}
|
autoFocus
|
sx={{ marginTop: 0, marginBottom: 0 }}
|
/>
|
<TextInput
|
label={translate('ra.auth.password')}
|
source="password"
|
variant="standard"
|
type="password"
|
disabled={loading}
|
validate={required()}
|
value={password}
|
onChange={e => setPassword(e.target.value)}
|
sx={{ marginTop: 0, marginBottom: 0 }}
|
/>
|
<Button
|
variant="contained"
|
type="submit"
|
disabled={loading || btnDisable}
|
fullWidth
|
sx={{
|
backgroundColor: "#3D4BA7"
|
}}
|
>
|
{loading && (
|
<CircularProgress size={25} thickness={2} />
|
)}
|
{translate('page.login.button.login')}
|
</Button>
|
|
<Box mt={1} mb={1} sx={{ textAlign: 'center' }}>or</Box>
|
</Box >
|
</Form>
|
</>
|
)
|
}
|
|
const RegisterForm = (props) => {
|
|
return (
|
<>
|
<Box
|
hidden={props.tab !== 1}
|
>
|
Register
|
</Box >
|
</>
|
)
|
}
|
|
export default Login;
|