LoginForm.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. import React, { useContext, useEffect, useState } from 'react';
  2. import { Button, Divider, Form, Grid, Header, Image, Message, Modal, Segment } from 'semantic-ui-react';
  3. import { Link, useNavigate, useSearchParams } from 'react-router-dom';
  4. import { UserContext } from '../context/User';
  5. import { API, getLogo, showError, showSuccess } from '../helpers';
  6. import { getOAuthState, onGitHubOAuthClicked } from './utils';
  7. const LoginForm = () => {
  8. const [inputs, setInputs] = useState({
  9. username: '',
  10. password: '',
  11. wechat_verification_code: ''
  12. });
  13. const [searchParams, setSearchParams] = useSearchParams();
  14. const [submitted, setSubmitted] = useState(false);
  15. const { username, password } = inputs;
  16. const [userState, userDispatch] = useContext(UserContext);
  17. let navigate = useNavigate();
  18. const [status, setStatus] = useState({});
  19. const logo = getLogo();
  20. useEffect(() => {
  21. if (searchParams.get('expired')) {
  22. showError('未登录或登录已过期,请重新登录!');
  23. }
  24. let status = localStorage.getItem('status');
  25. if (status) {
  26. status = JSON.parse(status);
  27. setStatus(status);
  28. }
  29. }, []);
  30. const [showWeChatLoginModal, setShowWeChatLoginModal] = useState(false);
  31. const onWeChatLoginClicked = () => {
  32. setShowWeChatLoginModal(true);
  33. };
  34. const onSubmitWeChatVerificationCode = async () => {
  35. const res = await API.get(
  36. `/api/oauth/wechat?code=${inputs.wechat_verification_code}`
  37. );
  38. const { success, message, data } = res.data;
  39. if (success) {
  40. userDispatch({ type: 'login', payload: data });
  41. localStorage.setItem('user', JSON.stringify(data));
  42. navigate('/');
  43. showSuccess('登录成功!');
  44. setShowWeChatLoginModal(false);
  45. } else {
  46. showError(message);
  47. }
  48. };
  49. function handleChange(e) {
  50. const { name, value } = e.target;
  51. setInputs((inputs) => ({ ...inputs, [name]: value }));
  52. }
  53. async function handleSubmit(e) {
  54. setSubmitted(true);
  55. if (username && password) {
  56. const res = await API.post(`/api/user/login`, {
  57. username,
  58. password
  59. });
  60. const { success, message, data } = res.data;
  61. if (success) {
  62. userDispatch({ type: 'login', payload: data });
  63. localStorage.setItem('user', JSON.stringify(data));
  64. navigate('/');
  65. showSuccess('登录成功!');
  66. } else {
  67. showError(message);
  68. }
  69. }
  70. }
  71. return (
  72. <Grid textAlign='center' style={{ marginTop: '48px' }}>
  73. <Grid.Column style={{ maxWidth: 450 }}>
  74. <Header as='h2' color='' textAlign='center'>
  75. <Image src={logo} /> 用户登录
  76. </Header>
  77. <Form size='large'>
  78. <Segment>
  79. <Form.Input
  80. fluid
  81. icon='user'
  82. iconPosition='left'
  83. placeholder='用户名'
  84. name='username'
  85. value={username}
  86. onChange={handleChange}
  87. />
  88. <Form.Input
  89. fluid
  90. icon='lock'
  91. iconPosition='left'
  92. placeholder='密码'
  93. name='password'
  94. type='password'
  95. value={password}
  96. onChange={handleChange}
  97. />
  98. <Button color='green' fluid size='large' onClick={handleSubmit}>
  99. 登录
  100. </Button>
  101. </Segment>
  102. </Form>
  103. <Message>
  104. 忘记密码?
  105. <Link to='/reset' className='btn btn-link'>
  106. 点击重置
  107. </Link>
  108. ; 没有账户?
  109. <Link to='/register' className='btn btn-link'>
  110. 点击注册
  111. </Link>
  112. </Message>
  113. {status.github_oauth || status.wechat_login ? (
  114. <>
  115. <Divider horizontal>Or</Divider>
  116. {status.github_oauth ? (
  117. <Button
  118. circular
  119. color='black'
  120. icon='github'
  121. onClick={()=>onGitHubOAuthClicked(status.github_client_id)}
  122. />
  123. ) : (
  124. <></>
  125. )}
  126. {status.wechat_login ? (
  127. <Button
  128. circular
  129. color='green'
  130. icon='wechat'
  131. onClick={onWeChatLoginClicked}
  132. />
  133. ) : (
  134. <></>
  135. )}
  136. </>
  137. ) : (
  138. <></>
  139. )}
  140. <Modal
  141. onClose={() => setShowWeChatLoginModal(false)}
  142. onOpen={() => setShowWeChatLoginModal(true)}
  143. open={showWeChatLoginModal}
  144. size={'mini'}
  145. >
  146. <Modal.Content>
  147. <Modal.Description>
  148. <Image src={status.wechat_qrcode} fluid />
  149. <div style={{ textAlign: 'center' }}>
  150. <p>
  151. 微信扫码关注公众号,输入「验证码」获取验证码(三分钟内有效)
  152. </p>
  153. </div>
  154. <Form size='large'>
  155. <Form.Input
  156. fluid
  157. placeholder='验证码'
  158. name='wechat_verification_code'
  159. value={inputs.wechat_verification_code}
  160. onChange={handleChange}
  161. />
  162. <Button
  163. color=''
  164. fluid
  165. size='large'
  166. onClick={onSubmitWeChatVerificationCode}
  167. >
  168. 登录
  169. </Button>
  170. </Form>
  171. </Modal.Description>
  172. </Modal.Content>
  173. </Modal>
  174. </Grid.Column>
  175. </Grid>
  176. );
  177. };
  178. export default LoginForm;