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
import { Form, Input, message, Button, Select, Row, Col, Popover, Progress } from 'antd';
6
import styles from './style.less';
陈帅's avatar
陈帅 committed
7 8 9
import { Dispatch } from 'redux';
import { IStateType } from './model';
import { FormComponentProps } from 'antd/lib/form';
陈帅's avatar
陈帅 committed
10
import router from 'umi/router';
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
  interval: number | undefined;
94

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

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

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

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

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

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

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

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

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

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