index.tsx 10.4 KB
Newer Older
1 2
import React, { Component } from 'react';
import { connect } from 'dva';
陈帅's avatar
陈帅 committed
3
import { formatMessage, FormattedMessage } from 'umi-plugin-react/locale';
zinkey's avatar
zinkey committed
4
import Link from 'umi/link';
陈帅's avatar
陈帅 committed
5 6
import { Form, Input, message, Button, Select, Row, Col, Popover, Progress } from 'antd';
import { Dispatch } from 'redux';
陈帅's avatar
陈帅 committed
7
import { FormComponentProps } from 'antd/es/form';
陈帅's avatar
陈帅 committed
8
import router from 'umi/router';
陈帅's avatar
陈帅 committed
9 10
import { IStateType } from './model';
import styles from './style.less';
11 12

const FormItem = Form.Item;
afc163's avatar
afc163 committed
13
const { Option } = Select;
14 15 16
const InputGroup = Input.Group;

const passwordStatusMap = {
17 18
  ok: (
    <div className={styles.success}>
19
      <FormattedMessage id="BLOCK_NAME.strength.strong" />
20 21 22 23
    </div>
  ),
  pass: (
    <div className={styles.warning}>
24
      <FormattedMessage id="BLOCK_NAME.strength.medium" />
25 26 27 28
    </div>
  ),
  poor: (
    <div className={styles.error}>
29
      <FormattedMessage id="BLOCK_NAME.strength.short" />
30 31
    </div>
  ),
32 33
};

陈帅's avatar
陈帅 committed
34 35 36 37 38
const passwordProgressMap: {
  ok: 'success';
  pass: 'normal';
  poor: 'exception';
} = {
39 40
  ok: 'success',
  pass: 'normal',
jim's avatar
jim committed
41
  poor: 'exception',
42 43
};

陈帅's avatar
陈帅 committed
44
interface BLOCK_NAME_CAMEL_CASEProps extends FormComponentProps {
陈帅's avatar
陈帅 committed
45
  dispatch: Dispatch<any>;
陈帅's avatar
陈帅 committed
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
  BLOCK_NAME_CAMEL_CASE: IStateType;
  submitting: boolean;
}
interface BLOCK_NAME_CAMEL_CASEState {
  count: number;
  confirmDirty: boolean;
  visible: boolean;
  help: string;
  prefix: string;
}

export interface IUserRegisterParams {
  mail: string;
  password: string;
  confirm: string;
  mobile: string;
  captcha: string;
  prefix: string;
}

@connect(
  ({
    BLOCK_NAME_CAMEL_CASE,
    loading,
  }: {
    BLOCK_NAME_CAMEL_CASE: IStateType;
    loading: {
      effects: {
        [key: string]: string;
      };
    };
  }) => ({
    BLOCK_NAME_CAMEL_CASE,
    submitting: loading.effects['BLOCK_NAME_CAMEL_CASE/submit'],
陈帅's avatar
陈帅 committed
80
  }),
陈帅's avatar
陈帅 committed
81 82 83 84 85 86
)
class PAGE_NAME_UPPER_CAMEL_CASE extends Component<
  BLOCK_NAME_CAMEL_CASEProps,
  BLOCK_NAME_CAMEL_CASEState
> {
  state: BLOCK_NAME_CAMEL_CASEState = {
87 88 89 90
    count: 0,
    confirmDirty: false,
    visible: false,
    help: '',
ddcat1115's avatar
ddcat1115 committed
91 92
    prefix: '86',
  };
陈帅's avatar
陈帅 committed
93

陈帅's avatar
陈帅 committed
94
  interval: number | undefined;
95

jim's avatar
jim committed
96
  componentDidUpdate() {
陈帅's avatar
陈帅 committed
97 98
    const { BLOCK_NAME_CAMEL_CASE, form } = this.props;
    const account = form.getFieldValue('mail');
99
    if (BLOCK_NAME_CAMEL_CASE.status === 'ok') {
陈帅's avatar
陈帅 committed
100
      message.success('注册成功!');
陈帅's avatar
陈帅 committed
101 102 103 104 105 106
      router.push({
        pathname: '/user/register-result',
        state: {
          account,
        },
      });
107 108
    }
  }
陈帅's avatar
陈帅 committed
109

110 111 112
  componentWillUnmount() {
    clearInterval(this.interval);
  }
陈帅's avatar
陈帅 committed
113

114 115 116
  onGetCaptcha = () => {
    let count = 59;
    this.setState({ count });
陈帅's avatar
陈帅 committed
117
    this.interval = window.setInterval(() => {
118 119 120 121 122 123
      count -= 1;
      this.setState({ count });
      if (count === 0) {
        clearInterval(this.interval);
      }
    }, 1000);
ddcat1115's avatar
ddcat1115 committed
124
  };
125 126

  getPasswordStatus = () => {
afc163's avatar
afc163 committed
127
    const { form } = this.props;
128 129 130 131 132 133 134
    const value = form.getFieldValue('password');
    if (value && value.length > 9) {
      return 'ok';
    }
    if (value && value.length > 5) {
      return 'pass';
    }
jim's avatar
jim committed
135
    return 'poor';
ddcat1115's avatar
ddcat1115 committed
136
  };
137

陈帅's avatar
陈帅 committed
138
  handleSubmit = (e: React.FormEvent) => {
139
    e.preventDefault();
陈帅's avatar
陈帅 committed
140 141
    const { form, dispatch } = this.props;
    form.validateFields({ force: true }, (err, values) => {
ddcat1115's avatar
ddcat1115 committed
142
      if (!err) {
陈帅's avatar
陈帅 committed
143 144
        const { prefix } = this.state;
        dispatch({
145
          type: 'BLOCK_NAME_CAMEL_CASE/submit',
ddcat1115's avatar
ddcat1115 committed
146 147
          payload: {
            ...values,
陈帅's avatar
陈帅 committed
148
            prefix,
ddcat1115's avatar
ddcat1115 committed
149 150
          },
        });
151
      }
ddcat1115's avatar
ddcat1115 committed
152 153
    });
  };
154

陈帅's avatar
陈帅 committed
155
  checkConfirm = (rule: any, value: string, callback: (messgae?: string) => void) => {
afc163's avatar
afc163 committed
156
    const { form } = this.props;
157
    if (value && value !== form.getFieldValue('password')) {
158
      callback(formatMessage({ id: 'BLOCK_NAME.password.twice' }));
159 160 161
    } else {
      callback();
    }
ddcat1115's avatar
ddcat1115 committed
162
  };
163

陈帅's avatar
陈帅 committed
164
  checkPassword = (rule: any, value: string, callback: (messgae?: string) => void) => {
陈帅's avatar
陈帅 committed
165
    const { visible, confirmDirty } = this.state;
166 167
    if (!value) {
      this.setState({
168
        help: formatMessage({ id: 'BLOCK_NAME.password.required' }),
169 170 171 172 173 174 175
        visible: !!value,
      });
      callback('error');
    } else {
      this.setState({
        help: '',
      });
陈帅's avatar
陈帅 committed
176
      if (!visible) {
177 178 179 180 181 182 183
        this.setState({
          visible: !!value,
        });
      }
      if (value.length < 6) {
        callback('error');
      } else {
afc163's avatar
afc163 committed
184
        const { form } = this.props;
陈帅's avatar
陈帅 committed
185
        if (value && confirmDirty) {
186 187 188 189 190
          form.validateFields(['confirm'], { force: true });
        }
        callback();
      }
    }
ddcat1115's avatar
ddcat1115 committed
191 192
  };

陈帅's avatar
陈帅 committed
193
  changePrefix = (value: string) => {
ddcat1115's avatar
ddcat1115 committed
194 195 196 197
    this.setState({
      prefix: value,
    });
  };
198 199

  renderPasswordProgress = () => {
afc163's avatar
afc163 committed
200
    const { form } = this.props;
201 202
    const value = form.getFieldValue('password');
    const passwordStatus = this.getPasswordStatus();
ddcat1115's avatar
ddcat1115 committed
203
    return value && value.length ? (
204 205
      <div className={styles[`progress-${passwordStatus}`]}>
        <Progress
陈帅's avatar
陈帅 committed
206
          default={passwordProgressMap[passwordStatus]}
207 208 209 210 211 212
          status={passwordProgressMap[passwordStatus]}
          className={styles.progress}
          strokeWidth={6}
          percent={value.length * 10 > 100 ? 100 : value.length * 10}
          showInfo={false}
        />
ddcat1115's avatar
ddcat1115 committed
213 214 215
      </div>
    ) : null;
  };
216 217

  render() {
Andreas Cederström's avatar
Andreas Cederström committed
218
    const { form, submitting } = this.props;
219
    const { getFieldDecorator } = form;
陈帅's avatar
陈帅 committed
220
    const { count, prefix, help, visible } = this.state;
221 222
    return (
      <div className={styles.main}>
223
        <h3>
224
          <FormattedMessage id="BLOCK_NAME.register.register" />
225
        </h3>
226 227 228
        <Form onSubmit={this.handleSubmit}>
          <FormItem>
            {getFieldDecorator('mail', {
ddcat1115's avatar
ddcat1115 committed
229 230 231
              rules: [
                {
                  required: true,
232
                  message: formatMessage({ id: 'BLOCK_NAME.email.required' }),
ddcat1115's avatar
ddcat1115 committed
233 234 235
                },
                {
                  type: 'email',
236
                  message: formatMessage({ id: 'BLOCK_NAME.email.wrong-format' }),
ddcat1115's avatar
ddcat1115 committed
237 238
                },
              ],
239
            })(
xiaohuoni's avatar
xiaohuoni committed
240 241 242
              <Input
                size="large"
                placeholder={formatMessage({ id: 'BLOCK_NAME.email.placeholder' })}
陈帅's avatar
陈帅 committed
243
              />,
244
            )}
245
          </FormItem>
陈帅's avatar
陈帅 committed
246
          <FormItem help={help}>
247
            <Popover
陈帅's avatar
陈帅 committed
248
              getPopupContainer={node =>
陈帅's avatar
陈帅 committed
249
                (node && node.parentNode ? (node.parentNode as HTMLElement) : node)
陈帅's avatar
陈帅 committed
250
              }
251
              content={
ddcat1115's avatar
ddcat1115 committed
252
                <div style={{ padding: '4px 0' }}>
253 254
                  {passwordStatusMap[this.getPasswordStatus()]}
                  {this.renderPasswordProgress()}
ddcat1115's avatar
ddcat1115 committed
255
                  <div style={{ marginTop: 10 }}>
256
                    <FormattedMessage id="BLOCK_NAME.strength.msg" />
ddcat1115's avatar
ddcat1115 committed
257
                  </div>
258 259 260 261
                </div>
              }
              overlayStyle={{ width: 240 }}
              placement="right"
陈帅's avatar
陈帅 committed
262
              visible={visible}
263 264
            >
              {getFieldDecorator('password', {
ddcat1115's avatar
ddcat1115 committed
265 266 267 268 269
                rules: [
                  {
                    validator: this.checkPassword,
                  },
                ],
270 271 272 273
              })(
                <Input
                  size="large"
                  type="password"
274
                  placeholder={formatMessage({ id: 'BLOCK_NAME.password.placeholder' })}
陈帅's avatar
陈帅 committed
275
                />,
276
              )}
277 278 279 280
            </Popover>
          </FormItem>
          <FormItem>
            {getFieldDecorator('confirm', {
ddcat1115's avatar
ddcat1115 committed
281 282 283
              rules: [
                {
                  required: true,
284
                  message: formatMessage({ id: 'BLOCK_NAME.confirm-password.required' }),
ddcat1115's avatar
ddcat1115 committed
285 286 287 288 289
                },
                {
                  validator: this.checkConfirm,
                },
              ],
290 291 292 293
            })(
              <Input
                size="large"
                type="password"
294
                placeholder={formatMessage({ id: 'BLOCK_NAME.confirm-password.placeholder' })}
陈帅's avatar
陈帅 committed
295
              />,
296
            )}
297 298
          </FormItem>
          <FormItem>
ddcat1115's avatar
ddcat1115 committed
299 300 301 302 303 304 305 306 307 308 309 310 311 312
            <InputGroup compact>
              <Select
                size="large"
                value={prefix}
                onChange={this.changePrefix}
                style={{ width: '20%' }}
              >
                <Option value="86">+86</Option>
                <Option value="87">+87</Option>
              </Select>
              {getFieldDecorator('mobile', {
                rules: [
                  {
                    required: true,
313
                    message: formatMessage({ id: 'BLOCK_NAME.phone-number.required' }),
ddcat1115's avatar
ddcat1115 committed
314 315
                  },
                  {
316
                    pattern: /^\d{11}$/,
317
                    message: formatMessage({ id: 'BLOCK_NAME.phone-number.wrong-format' }),
ddcat1115's avatar
ddcat1115 committed
318 319
                  },
                ],
320 321 322 323
              })(
                <Input
                  size="large"
                  style={{ width: '80%' }}
324
                  placeholder={formatMessage({ id: 'BLOCK_NAME.phone-number.placeholder' })}
陈帅's avatar
陈帅 committed
325
                />,
326
              )}
327 328 329 330 331 332
            </InputGroup>
          </FormItem>
          <FormItem>
            <Row gutter={8}>
              <Col span={16}>
                {getFieldDecorator('captcha', {
ddcat1115's avatar
ddcat1115 committed
333 334 335
                  rules: [
                    {
                      required: true,
336
                      message: formatMessage({ id: 'BLOCK_NAME.verification-code.required' }),
ddcat1115's avatar
ddcat1115 committed
337 338
                    },
                  ],
339 340 341
                })(
                  <Input
                    size="large"
342
                    placeholder={formatMessage({ id: 'BLOCK_NAME.verification-code.placeholder' })}
陈帅's avatar
陈帅 committed
343
                  />,
344
                )}
345 346 347
              </Col>
              <Col span={8}>
                <Button
ddcat1115's avatar
ddcat1115 committed
348
                  size="large"
陈帅's avatar
陈帅 committed
349
                  disabled={!!count}
350 351 352
                  className={styles.getCaptcha}
                  onClick={this.onGetCaptcha}
                >
353 354
                  {count
                    ? `${count} s`
355
                    : formatMessage({ id: 'BLOCK_NAME.register.get-verification-code' })}
356 357 358 359 360
                </Button>
              </Col>
            </Row>
          </FormItem>
          <FormItem>
ddcat1115's avatar
ddcat1115 committed
361 362
            <Button
              size="large"
Andreas Cederström's avatar
Andreas Cederström committed
363
              loading={submitting}
ddcat1115's avatar
ddcat1115 committed
364 365 366 367
              className={styles.submit}
              type="primary"
              htmlType="submit"
            >
368
              <FormattedMessage id="BLOCK_NAME.register.register" />
369
            </Button>
lijiehua's avatar
lijiehua committed
370
            <Link className={styles.login} to="/user/login">
371
              <FormattedMessage id="BLOCK_NAME.register.sign-in" />
ddcat1115's avatar
ddcat1115 committed
372
            </Link>
373 374 375 376 377 378
          </FormItem>
        </Form>
      </div>
    );
  }
}
lijiehua's avatar
lijiehua committed
379

陈帅's avatar
陈帅 committed
380
export default Form.create<BLOCK_NAME_CAMEL_CASEProps>()(PAGE_NAME_UPPER_CAMEL_CASE);