register-form.jsx 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import { useState } from 'react'
  2. import PropTypes from 'prop-types'
  3. import { postJSON } from '@/infrastructure/fetch-json'
  4. import OLButton from '@/features/ui/components/ol/ol-button'
  5. import OLForm from '@/features/ui/components/ol/ol-form'
  6. import OLFormControl from '@/features/ui/components/ol/ol-form-control'
  7. function RegisterForm({
  8. setRegistrationSuccess,
  9. setEmails,
  10. setRegisterError,
  11. setFailedEmails,
  12. }) {
  13. const [isLoading, setIsLoading] = useState(false)
  14. function handleRegister(event) {
  15. event.preventDefault()
  16. const formData = new FormData(event.target)
  17. const formDataAsEntries = formData.entries()
  18. const formDataAsObject = Object.fromEntries(formDataAsEntries)
  19. const emailString = formDataAsObject.email
  20. setRegistrationSuccess(false)
  21. setRegisterError(false)
  22. setEmails([])
  23. registerGivenUsers(parseEmails(emailString))
  24. }
  25. async function registerGivenUsers(emails) {
  26. const registeredEmails = []
  27. const failingEmails = []
  28. setIsLoading(true)
  29. for (const email of emails) {
  30. try {
  31. const result = await registerUser(email)
  32. registeredEmails.push(result)
  33. } catch {
  34. failingEmails.push(email)
  35. }
  36. }
  37. setIsLoading(false)
  38. if (registeredEmails.length > 0) setRegistrationSuccess(true)
  39. if (failingEmails.length > 0) {
  40. setRegisterError(true)
  41. setFailedEmails(failingEmails)
  42. }
  43. setEmails(registeredEmails)
  44. }
  45. function registerUser(email) {
  46. const options = { email }
  47. const url = `/admin/register`
  48. return postJSON(url, { body: options })
  49. }
  50. return (
  51. <OLForm onSubmit={handleRegister}>
  52. <div className="d-flex gap-2 flex-wrap">
  53. <div className="flex-grow-1 max-width">
  54. <OLFormControl
  55. className="form-control"
  56. name="email"
  57. type="text"
  58. placeholder="jane@example.com, joe@example.com"
  59. aria-label="emails to register"
  60. aria-describedby="input-details"
  61. />
  62. <p id="input-details" className="sr-only">
  63. Enter the emails you would like to register and separate them using
  64. commas
  65. </p>
  66. </div>
  67. <OLButton type="submit" className="ms-auto" isLoading={isLoading}>
  68. Register
  69. </OLButton>
  70. </div>
  71. </OLForm>
  72. )
  73. }
  74. function parseEmails(emailsText) {
  75. const regexBySpaceOrComma = /[\s,]+/
  76. let emails = emailsText.split(regexBySpaceOrComma)
  77. emails.map(email => email.trim())
  78. emails = emails.filter(email => email.indexOf('@') !== -1)
  79. return emails
  80. }
  81. RegisterForm.propTypes = {
  82. setRegistrationSuccess: PropTypes.func,
  83. setEmails: PropTypes.func,
  84. setRegisterError: PropTypes.func,
  85. setFailedEmails: PropTypes.func,
  86. }
  87. export default RegisterForm