diff --git a/package.json b/package.json index 1be1693..62d38f1 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/App.js b/src/App.js index 5b3905c..91e2cb2 100644 --- a/src/App.js +++ b/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() { - + }> - + + + + }> + + + }> diff --git a/src/component/Login/LoginForm.js b/src/component/Login/LoginForm.js index 72aef8c..dee0548 100644 --- a/src/component/Login/LoginForm.js +++ b/src/component/Login/LoginForm.js @@ -412,7 +412,7 @@ function LoginForm() { 忘记密码 - 注册账号 + 注册账号 diff --git a/src/component/Login/Register.js b/src/component/Login/Register.js new file mode 100644 index 0000000..7905c44 --- /dev/null +++ b/src/component/Login/Register.js @@ -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 ( + + <> + {!emailActive && + + + + + 注册 {title} + + + + + 电子邮箱 + + + + 密码 + + + + 密码 + + + {regCaptcha && ( + + + + 验证码 + + + {" "} + + {captchaData === null && ( + + + + )} + {captchaData !== null && ( + + )} + + + )} + + + 注册账号 + + + + + + + 返回登录 + + + 忘记密码 + + + } + {emailActive && + + + + + + 邮件激活 + + 一封激活邮件已经发送至您的邮箱,请访问邮件中的链接以继续完成注册。 + + + } + + > + + ); +} + +export default Register; diff --git a/src/component/Placeholder/PageLoading.js b/src/component/Placeholder/PageLoading.js index 623e1be..c8248c7 100644 --- a/src/component/Placeholder/PageLoading.js +++ b/src/component/Placeholder/PageLoading.js @@ -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 ( + + ); +}; -const MyLoader = (props) => ( - -) - -function PageLoading (){ - +function PageLoading() { const classes = useStyles(); return ( - - + + - - ) + ); } -export default PageLoading \ No newline at end of file +export default PageLoading; diff --git a/src/middleware/NoAuthRoute.js b/src/middleware/NoAuthRoute.js new file mode 100644 index 0000000..23613ef --- /dev/null +++ b/src/middleware/NoAuthRoute.js @@ -0,0 +1,28 @@ +import React from "react"; +import Auth from "./Auth" +import { + Route, + Redirect, + } from "react-router-dom"; + +function NoAuthRoute({ children, ...rest }) { + return ( + + !Auth.Check(rest.isLogin) ? ( + children + ) : ( + + ) + } + /> + ); + } + +export default NoAuthRoute \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index cae0282..91303cc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -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"