resend-confirmation-code-modal.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. import { useEffect, useState } from 'react'
  2. import { useTranslation } from 'react-i18next'
  3. import { FetchError, postJSON } from '@/infrastructure/fetch-json'
  4. import useAsync from '../../../../shared/hooks/use-async'
  5. import { UserEmailData } from '../../../../../../types/user-email'
  6. import OLButton from '@/shared/components/ol/ol-button'
  7. import {
  8. OLModal,
  9. OLModalBody,
  10. OLModalFooter,
  11. OLModalHeader,
  12. OLModalTitle,
  13. } from '@/shared/components/ol/ol-modal'
  14. import { ConfirmEmailForm } from '@/features/settings/components/emails/confirm-email-form'
  15. type ResendConfirmationEmailButtonProps = {
  16. email: UserEmailData['email']
  17. groupLoading: boolean
  18. setGroupLoading: (loading: boolean) => void
  19. onSuccess: () => void
  20. triggerVariant: 'link' | 'secondary'
  21. }
  22. function ResendConfirmationCodeModal({
  23. email,
  24. groupLoading,
  25. setGroupLoading,
  26. onSuccess,
  27. triggerVariant,
  28. }: ResendConfirmationEmailButtonProps) {
  29. const { t } = useTranslation()
  30. const { error, isLoading, isError, runAsync } = useAsync()
  31. const [modalVisible, setModalVisible] = useState(false)
  32. useEffect(() => {
  33. setGroupLoading(isLoading)
  34. }, [isLoading, setGroupLoading])
  35. const handleResendConfirmationEmail = async () => {
  36. await runAsync(
  37. postJSON('/user/emails/send-confirmation-code', { body: { email } })
  38. )
  39. .catch(() => {})
  40. .finally(() => setModalVisible(true))
  41. }
  42. const rateLimited =
  43. error && error instanceof FetchError && error.response?.status === 429
  44. return (
  45. <>
  46. {modalVisible && (
  47. <OLModal
  48. animation
  49. show={modalVisible}
  50. onHide={() => setModalVisible(false)}
  51. id="action-project-modal"
  52. backdrop="static"
  53. >
  54. <OLModalHeader>
  55. <OLModalTitle>{t('confirm_your_email')}</OLModalTitle>
  56. </OLModalHeader>
  57. <OLModalBody>
  58. <ConfirmEmailForm
  59. isModal
  60. flow="resend"
  61. interstitial={false}
  62. resendEndpoint="/user/emails/resend-confirmation-code"
  63. confirmationEndpoint="/user/emails/confirm-code"
  64. email={email}
  65. onSuccessfulConfirmation={() => {
  66. onSuccess()
  67. setModalVisible(false)
  68. }}
  69. outerError={
  70. isError
  71. ? rateLimited
  72. ? t('too_many_requests')
  73. : t('generic_something_went_wrong')
  74. : undefined
  75. }
  76. />
  77. </OLModalBody>
  78. <OLModalFooter>
  79. <OLButton
  80. variant="secondary"
  81. disabled={isLoading}
  82. onClick={() => setModalVisible(false)}
  83. >
  84. {t('cancel')}
  85. </OLButton>
  86. </OLModalFooter>
  87. </OLModal>
  88. )}
  89. <OLButton
  90. variant={triggerVariant}
  91. disabled={groupLoading}
  92. isLoading={isLoading}
  93. loadingLabel={t('sending')}
  94. onClick={handleResendConfirmationEmail}
  95. className={triggerVariant === 'link' ? 'btn-inline-link' : undefined}
  96. >
  97. {t('send_confirmation_code')}
  98. </OLButton>
  99. </>
  100. )
  101. }
  102. export default ResendConfirmationCodeModal