registerForm.tsx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. import {Component} from 'react';
  2. import {browserHistory} from 'react-router';
  3. import {ClassNames} from '@emotion/react';
  4. import styled from '@emotion/styled';
  5. import {Client} from 'sentry/api';
  6. import Form from 'sentry/components/deprecatedforms/form';
  7. import PasswordField from 'sentry/components/deprecatedforms/passwordField';
  8. import RadioBooleanField from 'sentry/components/deprecatedforms/radioBooleanField';
  9. import TextField from 'sentry/components/deprecatedforms/textField';
  10. import ExternalLink from 'sentry/components/links/externalLink';
  11. import {t, tct} from 'sentry/locale';
  12. import ConfigStore from 'sentry/stores/configStore';
  13. import {AuthConfig} from 'sentry/types';
  14. import {formFooterClass} from 'sentry/views/auth/login';
  15. const SubscribeField = () => (
  16. <RadioBooleanField
  17. name="subscribe"
  18. yesLabel={t('Yes, I would like to receive updates via email')}
  19. noLabel={t("No, I'd prefer not to receive these updates")}
  20. help={tct(
  21. `We'd love to keep you updated via email with product and feature
  22. announcements, promotions, educational materials, and events. Our
  23. updates focus on relevant information, and we'll never sell your data
  24. to third parties. See our [link] for more details.`,
  25. {
  26. link: <a href="https://sentry.io/privacy/">Privacy Policy</a>,
  27. }
  28. )}
  29. />
  30. );
  31. type Props = {
  32. api: Client;
  33. authConfig: AuthConfig;
  34. };
  35. type State = {
  36. errorMessage: null | string;
  37. errors: Record<string, string>;
  38. };
  39. class RegisterForm extends Component<Props, State> {
  40. state: State = {
  41. errorMessage: null,
  42. errors: {},
  43. };
  44. handleSubmit: Form['props']['onSubmit'] = async (data, onSuccess, onError) => {
  45. const {api} = this.props;
  46. try {
  47. const response = await api.requestPromise('/auth/register/', {
  48. method: 'POST',
  49. data,
  50. });
  51. onSuccess(data);
  52. // TODO(epurkhiser): There is more we need to do to setup the user. but
  53. // definitely primarily we need to init our user.
  54. ConfigStore.set('user', response.user);
  55. browserHistory.push({pathname: response.nextUri});
  56. } catch (e) {
  57. if (!e.responseJSON || !e.responseJSON.errors) {
  58. onError(e);
  59. return;
  60. }
  61. let message = e.responseJSON.detail;
  62. if (e.responseJSON.errors.__all__) {
  63. message = e.responseJSON.errors.__all__;
  64. }
  65. this.setState({
  66. errorMessage: message,
  67. errors: e.responseJSON.errors || {},
  68. });
  69. onError(e);
  70. }
  71. };
  72. render() {
  73. const {hasNewsletter} = this.props.authConfig;
  74. const {errorMessage, errors} = this.state;
  75. return (
  76. <ClassNames>
  77. {({css}) => (
  78. <Form
  79. initialData={{subscribe: true}}
  80. submitLabel={t('Continue')}
  81. onSubmit={this.handleSubmit}
  82. footerClass={css`
  83. ${formFooterClass}
  84. `}
  85. errorMessage={errorMessage}
  86. extraButton={
  87. <PrivacyPolicyLink href="https://sentry.io/privacy/">
  88. {t('Privacy Policy')}
  89. </PrivacyPolicyLink>
  90. }
  91. >
  92. <TextField
  93. name="name"
  94. placeholder={t('Jane Bloggs')}
  95. label={t('Name')}
  96. error={errors.name}
  97. required
  98. />
  99. <TextField
  100. name="username"
  101. placeholder={t('you@example.com')}
  102. label={t('Email')}
  103. error={errors.username}
  104. required
  105. />
  106. <PasswordField
  107. name="password"
  108. placeholder={t('something super secret')}
  109. label={t('Password')}
  110. error={errors.password}
  111. required
  112. />
  113. {hasNewsletter && <SubscribeField />}
  114. </Form>
  115. )}
  116. </ClassNames>
  117. );
  118. }
  119. }
  120. const PrivacyPolicyLink = styled(ExternalLink)`
  121. color: ${p => p.theme.gray300};
  122. &:hover {
  123. color: ${p => p.theme.textColor};
  124. }
  125. `;
  126. export default RegisterForm;