mirror of
https://github.com/cloudreve/frontend.git
synced 2025-12-25 19:52:48 +00:00
This commit is contained in:
parent
d6968cab07
commit
5ad86777f2
|
|
@ -14,7 +14,7 @@
|
|||
"qrcode-react": "^0.1.16",
|
||||
"react": "^16.12.0",
|
||||
"react-addons-update": "^15.6.2",
|
||||
"react-content-loader": "^4.3.2",
|
||||
"react-content-loader": "^5.0.2",
|
||||
"react-dnd": "^9.5.1",
|
||||
"react-dnd-html5-backend": "^9.5.1",
|
||||
"react-dom": "^16.12.0",
|
||||
|
|
|
|||
12
src/App.js
12
src/App.js
|
|
@ -11,6 +11,7 @@ import { CssBaseline, makeStyles, ThemeProvider } from "@material-ui/core";
|
|||
import PageLoading from "./component/Placeholder/PageLoading.js";
|
||||
import {changeThemeColor} from "./untils";
|
||||
import NotFound from "./component/Share/NotFound";
|
||||
import NoAuthRoute from "./middleware/NoAuthRoute";
|
||||
|
||||
// Lazy loads
|
||||
const LoginForm = React.lazy(() => import("./component/Login/LoginForm"));
|
||||
|
|
@ -31,6 +32,7 @@ const Tasks = React.lazy(() => import("./component/Setting/Tasks"));
|
|||
const Profile = React.lazy(() => import("./component/Setting/Profile"));
|
||||
const UserSetting = React.lazy(() => import("./component/Setting/UserSetting"));
|
||||
const QQCallback = React.lazy(() => import("./component/Login/QQ"));
|
||||
const Register = React.lazy(() => import("./component/Login/Register"));
|
||||
|
||||
export default function App() {
|
||||
const themeConfig = useSelector(state => state.siteConfig.theme);
|
||||
|
|
@ -176,11 +178,17 @@ export default function App() {
|
|||
</Suspense>
|
||||
</AuthRoute>
|
||||
|
||||
<Route path={`${path}login`} exact>
|
||||
<NoAuthRoute path={`${path}login`} exact>
|
||||
<Suspense fallback={<PageLoading />}>
|
||||
<LoginForm />
|
||||
</Suspense>
|
||||
</Route>
|
||||
</NoAuthRoute>
|
||||
|
||||
<NoAuthRoute path={`${path}signup`} exact>
|
||||
<Suspense fallback={<PageLoading />}>
|
||||
<Register />
|
||||
</Suspense>
|
||||
</NoAuthRoute>
|
||||
|
||||
<Route path={`${path}login/qq`}>
|
||||
<Suspense fallback={<PageLoading />}>
|
||||
|
|
|
|||
|
|
@ -412,7 +412,7 @@ function LoginForm() {
|
|||
<Link href={"/Member/FindPwd"}>忘记密码</Link>
|
||||
</div>
|
||||
<div>
|
||||
<Link href={"/SignUp"}>注册账号</Link>
|
||||
<Link href={"/#/signup"}>注册账号</Link>
|
||||
</div>
|
||||
</div>
|
||||
</Paper>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,286 @@
|
|||
import React, { useCallback, useState, useEffect } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import RegIcon from '@material-ui/icons/AssignmentIndOutlined';
|
||||
import { makeStyles } from "@material-ui/core";
|
||||
import {
|
||||
toggleSnackbar,
|
||||
} from "../../actions/index";
|
||||
import Placeholder from "../Placeholder/Captcha";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import API from "../../middleware/Api";
|
||||
import Auth from "../../middleware/Auth";
|
||||
import {
|
||||
Button,
|
||||
FormControl,
|
||||
Divider,
|
||||
Link,
|
||||
Input,
|
||||
InputLabel,
|
||||
Paper,
|
||||
Avatar,
|
||||
Typography
|
||||
} from "@material-ui/core";
|
||||
import EmailIcon from "@material-ui/icons/EmailOutlined";
|
||||
const useStyles = makeStyles(theme => ({
|
||||
layout: {
|
||||
width: "auto",
|
||||
marginTop: "110px",
|
||||
marginLeft: theme.spacing(3),
|
||||
marginRight: theme.spacing(3),
|
||||
[theme.breakpoints.up("sm")]: {
|
||||
width: 400,
|
||||
marginLeft: "auto",
|
||||
marginRight: "auto"
|
||||
},
|
||||
marginBottom: 110
|
||||
},
|
||||
paper: {
|
||||
marginTop: theme.spacing(8),
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
padding: `${theme.spacing(2)}px ${theme.spacing(3)}px ${theme.spacing(
|
||||
3
|
||||
)}px`
|
||||
},
|
||||
avatar: {
|
||||
margin: theme.spacing(1),
|
||||
backgroundColor: theme.palette.secondary.main
|
||||
},
|
||||
form: {
|
||||
width: "100%", // Fix IE 11 issue.
|
||||
marginTop: theme.spacing(1)
|
||||
},
|
||||
submit: {
|
||||
marginTop: theme.spacing(3)
|
||||
},
|
||||
link: {
|
||||
marginTop: "20px",
|
||||
display: "flex",
|
||||
width: "100%",
|
||||
justifyContent: "space-between"
|
||||
},
|
||||
captchaContainer: {
|
||||
display: "flex",
|
||||
marginTop: "10px"
|
||||
},
|
||||
captchaPlaceholder: {
|
||||
width: 200
|
||||
},
|
||||
buttonContainer: {
|
||||
display: "flex"
|
||||
},
|
||||
authnLink: {
|
||||
textAlign: "center",
|
||||
marginTop: 16
|
||||
},
|
||||
avatarSuccess:{
|
||||
margin: theme.spacing(1),
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
},
|
||||
}));
|
||||
|
||||
function Register() {
|
||||
const [input,setInput] = useState({
|
||||
"email":"",
|
||||
"password":"",
|
||||
"password_repeat":"",
|
||||
"captcha":"",
|
||||
});
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [emailActive, setEmailActive] = useState(false);
|
||||
const [captchaData, setCaptchaData] = useState(null);
|
||||
|
||||
const title = useSelector(state => state.siteConfig.title);
|
||||
const regCaptcha = useSelector(state => state.siteConfig.regCaptcha);
|
||||
|
||||
const dispatch = useDispatch();
|
||||
const ToggleSnackbar = useCallback(
|
||||
(vertical, horizontal, msg, color) =>
|
||||
dispatch(toggleSnackbar(vertical, horizontal, msg, color)),
|
||||
[dispatch]
|
||||
);
|
||||
const history = useHistory();
|
||||
|
||||
const handleInputChange = name => e => {
|
||||
setInput({
|
||||
...input,
|
||||
[name]:e.target.value
|
||||
})
|
||||
}
|
||||
|
||||
const classes = useStyles();
|
||||
|
||||
const refreshCaptcha = () => {
|
||||
API.get("/site/captcha")
|
||||
.then(response => {
|
||||
setCaptchaData(response.data);
|
||||
})
|
||||
.catch(error => {
|
||||
ToggleSnackbar(
|
||||
"top",
|
||||
"right",
|
||||
"无法加载验证码:" + error.message,
|
||||
"error"
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
const register = e =>{
|
||||
e.preventDefault();
|
||||
|
||||
if (input.password !== input.password_repeat){
|
||||
ToggleSnackbar("top", "right", "两次密码输入不一致", "warning");
|
||||
}
|
||||
|
||||
setLoading(true);
|
||||
API.post("/user", {
|
||||
userName: input.email,
|
||||
Password: input.password,
|
||||
captchaCode: input.captcha
|
||||
})
|
||||
.then(response => {
|
||||
setLoading(false);
|
||||
if (response.rawData.code === 203){
|
||||
setEmailActive(true);
|
||||
}else{
|
||||
history.push("/login?username="+input.email)
|
||||
ToggleSnackbar("top", "right", "注册成功", "success");
|
||||
}
|
||||
|
||||
})
|
||||
.catch(error => {
|
||||
setLoading(false);
|
||||
ToggleSnackbar("top", "right", error.message, "warning");
|
||||
refreshCaptcha();
|
||||
});
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (regCaptcha) {
|
||||
refreshCaptcha();
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className={classes.layout}>
|
||||
<>
|
||||
{!emailActive && <Paper className={classes.paper}>
|
||||
<Avatar className={classes.avatar}>
|
||||
<RegIcon />
|
||||
</Avatar>
|
||||
<Typography component="h1" variant="h5">
|
||||
注册 {title}
|
||||
</Typography>
|
||||
|
||||
<form className={classes.form} onSubmit={register}>
|
||||
<FormControl margin="normal" required fullWidth>
|
||||
<InputLabel htmlFor="email">电子邮箱</InputLabel>
|
||||
<Input
|
||||
id="email"
|
||||
type="email"
|
||||
name="email"
|
||||
onChange={handleInputChange("email")}
|
||||
autoComplete
|
||||
value={input.email}
|
||||
autoFocus
|
||||
/>
|
||||
</FormControl>
|
||||
<FormControl margin="normal" required fullWidth>
|
||||
<InputLabel htmlFor="password">密码</InputLabel>
|
||||
<Input
|
||||
name="password"
|
||||
onChange={handleInputChange("password")}
|
||||
type="password"
|
||||
id="password"
|
||||
value={input.password}
|
||||
autoComplete
|
||||
/>
|
||||
</FormControl>
|
||||
<FormControl margin="normal" required fullWidth>
|
||||
<InputLabel htmlFor="password">密码</InputLabel>
|
||||
<Input
|
||||
name="pwdRepeat"
|
||||
onChange={handleInputChange("password_repeat")}
|
||||
type="password"
|
||||
id="pwdRepeat"
|
||||
value={input.password_repeat}
|
||||
autoComplete />
|
||||
</FormControl>
|
||||
{regCaptcha && (
|
||||
<div className={classes.captchaContainer}>
|
||||
<FormControl margin="normal" required fullWidth>
|
||||
<InputLabel htmlFor="captcha">
|
||||
验证码
|
||||
</InputLabel>
|
||||
<Input
|
||||
name="captcha"
|
||||
onChange={handleInputChange("captcha")}
|
||||
type="text"
|
||||
id="captcha"
|
||||
value={input.captcha}
|
||||
autoComplete
|
||||
/>
|
||||
</FormControl>{" "}
|
||||
<div>
|
||||
{captchaData === null && (
|
||||
<div
|
||||
className={
|
||||
classes.captchaPlaceholder
|
||||
}
|
||||
>
|
||||
<Placeholder />
|
||||
</div>
|
||||
)}
|
||||
{captchaData !== null && (
|
||||
<img
|
||||
src={captchaData}
|
||||
alt="captcha"
|
||||
onClick={refreshCaptcha}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<Button
|
||||
type="submit"
|
||||
fullWidth
|
||||
variant="contained"
|
||||
color="primary"
|
||||
disabled={loading}
|
||||
className={classes.submit}
|
||||
>
|
||||
注册账号
|
||||
</Button>
|
||||
</form>
|
||||
|
||||
<Divider />
|
||||
<div className={classes.link}>
|
||||
<div>
|
||||
<Link href={"/#/login"}>返回登录</Link>
|
||||
</div>
|
||||
<div>
|
||||
<Link href={"/SignUp"}>忘记密码</Link>
|
||||
</div>
|
||||
</div>
|
||||
</Paper>}
|
||||
{emailActive &&
|
||||
<Paper className={classes.paper}>
|
||||
<Avatar className={classes.avatarSuccess}>
|
||||
<EmailIcon />
|
||||
</Avatar>
|
||||
<Typography component="h1" variant="h5">
|
||||
邮件激活
|
||||
</Typography>
|
||||
<Typography style={{marginTop:"10px"}}>一封激活邮件已经发送至您的邮箱,请访问邮件中的链接以继续完成注册。</Typography>
|
||||
|
||||
</Paper>
|
||||
}
|
||||
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Register;
|
||||
|
|
@ -1,35 +1,36 @@
|
|||
import React from "react"
|
||||
import ContentLoader, { Facebook } from "react-content-loader"
|
||||
import {makeStyles} from "@material-ui/core/styles";
|
||||
import React from "react";
|
||||
import ContentLoader, { Facebook } from "react-content-loader";
|
||||
import { makeStyles, useTheme } from "@material-ui/core/styles";
|
||||
|
||||
const useStyles = makeStyles(theme => ({
|
||||
loader:{
|
||||
width:"80%",
|
||||
loader: {
|
||||
width: "80%",
|
||||
[theme.breakpoints.up("md")]: {
|
||||
width:" 50%",
|
||||
width: " 50%"
|
||||
},
|
||||
|
||||
marginTop:30,
|
||||
},
|
||||
marginTop: 30
|
||||
}
|
||||
}));
|
||||
|
||||
const MyLoader = props => {
|
||||
return (
|
||||
<Facebook className={props.className} />
|
||||
);
|
||||
};
|
||||
|
||||
const MyLoader = (props) => (
|
||||
<Facebook className={props.className}/>
|
||||
)
|
||||
|
||||
function PageLoading (){
|
||||
|
||||
function PageLoading() {
|
||||
const classes = useStyles();
|
||||
|
||||
return (
|
||||
<div style={{
|
||||
textAlign:"center",
|
||||
}}>
|
||||
<MyLoader className={classes.loader}/>
|
||||
<div
|
||||
style={{
|
||||
textAlign: "center"
|
||||
}}
|
||||
>
|
||||
<MyLoader className={classes.loader} />
|
||||
</div>
|
||||
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export default PageLoading
|
||||
export default PageLoading;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
import React from "react";
|
||||
import Auth from "./Auth"
|
||||
import {
|
||||
Route,
|
||||
Redirect,
|
||||
} from "react-router-dom";
|
||||
|
||||
function NoAuthRoute({ children, ...rest }) {
|
||||
return (
|
||||
<Route
|
||||
{...rest}
|
||||
render={({ location }) =>
|
||||
!Auth.Check(rest.isLogin) ? (
|
||||
children
|
||||
) : (
|
||||
<Redirect
|
||||
to={{
|
||||
pathname: "/home",
|
||||
state: { from: location }
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default NoAuthRoute
|
||||
|
|
@ -8557,10 +8557,10 @@ react-app-polyfill@^1.0.4:
|
|||
regenerator-runtime "0.13.3"
|
||||
whatwg-fetch "3.0.0"
|
||||
|
||||
react-content-loader@^4.3.2:
|
||||
version "4.3.2"
|
||||
resolved "https://registry.yarnpkg.com/react-content-loader/-/react-content-loader-4.3.2.tgz#2f6546c883707d399a2abc2efd00edcb8f584618"
|
||||
integrity sha512-Af2RW2G57+mFRXsiSXROtgvz3KmPz0lATRHNUpJ57DyVw6SRzDRNRXo04I2xhcwmwVnXsfx4s2hsHrU+Lq5jRw==
|
||||
react-content-loader@^5.0.2:
|
||||
version "5.0.2"
|
||||
resolved "https://registry.yarnpkg.com/react-content-loader/-/react-content-loader-5.0.2.tgz#f4d417ac2b3a913a4b5e406b8b36ff724bcfe15b"
|
||||
integrity sha512-d9+/FX640VXyO+9dBgMWaHD5IL0+tGsCAFBhYPGNziPx2abTMUBXL1+oIlenOTYlxuOWDcUcpmgjj4Ws+0xdhA==
|
||||
|
||||
react-dev-utils@^9.1.0:
|
||||
version "9.1.0"
|
||||
|
|
|
|||
Loading…
Reference in New Issue