resend-confirmation-code-modal.tsx 3.2 KB

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