organizationJoinRequest.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import {Component} from 'react';
  2. import {Params} from 'react-router/lib/Router';
  3. import styled from '@emotion/styled';
  4. import {addErrorMessage} from 'app/actionCreators/indicator';
  5. import NarrowLayout from 'app/components/narrowLayout';
  6. import {IconMegaphone} from 'app/icons';
  7. import {t, tct} from 'app/locale';
  8. import space from 'app/styles/space';
  9. import {trackAdhocEvent} from 'app/utils/analytics';
  10. import EmailField from 'app/views/settings/components/forms/emailField';
  11. import Form from 'app/views/settings/components/forms/form';
  12. type Props = {
  13. params: Params;
  14. };
  15. type State = {
  16. submitSuccess: boolean | null;
  17. };
  18. class OrganizationJoinRequest extends Component<Props, State> {
  19. state: State = {
  20. submitSuccess: null,
  21. };
  22. componentDidMount() {
  23. const {orgId} = this.props.params;
  24. trackAdhocEvent({
  25. eventKey: 'join_request.viewed',
  26. org_slug: orgId,
  27. });
  28. }
  29. handleSubmitSuccess = () => {
  30. this.setState({submitSuccess: true});
  31. };
  32. handleSubmitError() {
  33. addErrorMessage(t('Request to join failed'));
  34. }
  35. handleCancel = e => {
  36. e.preventDefault();
  37. const {orgId} = this.props.params;
  38. window.location.assign(`/auth/login/${orgId}/`);
  39. };
  40. render() {
  41. const {orgId} = this.props.params;
  42. const {submitSuccess} = this.state;
  43. if (submitSuccess) {
  44. return (
  45. <NarrowLayout maxWidth="550px">
  46. <SuccessModal>
  47. <StyledIconMegaphone size="5em" />
  48. <StyledHeader>{t('Request Sent')}</StyledHeader>
  49. <StyledText>{t('Your request to join has been sent.')}</StyledText>
  50. <ReceiveEmailMessage>
  51. {tct('You will receive an email when your request is approved.', {orgId})}
  52. </ReceiveEmailMessage>
  53. </SuccessModal>
  54. </NarrowLayout>
  55. );
  56. }
  57. return (
  58. <NarrowLayout maxWidth="650px">
  59. <StyledIconMegaphone size="5em" />
  60. <StyledHeader>{t('Request to Join')}</StyledHeader>
  61. <StyledText>
  62. {tct('Ask the admins if you can join the [orgId] organization.', {
  63. orgId,
  64. })}
  65. </StyledText>
  66. <Form
  67. requireChanges
  68. apiEndpoint={`/organizations/${orgId}/join-request/`}
  69. apiMethod="POST"
  70. submitLabel={t('Request to Join')}
  71. onSubmitSuccess={this.handleSubmitSuccess}
  72. onSubmitError={this.handleSubmitError}
  73. onCancel={this.handleCancel}
  74. >
  75. <StyledEmailField
  76. name="email"
  77. inline={false}
  78. label={t('Email Address')}
  79. placeholder="name@example.com"
  80. />
  81. </Form>
  82. </NarrowLayout>
  83. );
  84. }
  85. }
  86. const SuccessModal = styled('div')`
  87. display: grid;
  88. justify-items: center;
  89. text-align: center;
  90. padding-top: 10px;
  91. padding-bottom: ${space(4)};
  92. `;
  93. const StyledIconMegaphone = styled(IconMegaphone)`
  94. padding-bottom: ${space(3)};
  95. `;
  96. const StyledHeader = styled('h3')`
  97. margin-bottom: ${space(1)};
  98. `;
  99. const StyledText = styled('p')`
  100. margin-bottom: 0;
  101. `;
  102. const ReceiveEmailMessage = styled(StyledText)`
  103. max-width: 250px;
  104. `;
  105. const StyledEmailField = styled(EmailField)`
  106. padding-top: ${space(2)};
  107. padding-left: 0;
  108. `;
  109. export default OrganizationJoinRequest;