make-primary.tsx 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import Tooltip from '../../../../../shared/components/tooltip'
  2. import { Button } from 'react-bootstrap'
  3. import { useTranslation } from 'react-i18next'
  4. import {
  5. inReconfirmNotificationPeriod,
  6. institutionAlreadyLinked,
  7. } from '../../../utils/selectors'
  8. import { postJSON } from '../../../../../infrastructure/fetch-json'
  9. import {
  10. State,
  11. useUserEmailsContext,
  12. } from '../../../context/user-email-context'
  13. import { UserEmailData } from '../../../../../../../types/user-email'
  14. import { UseAsyncReturnType } from '../../../../../shared/hooks/use-async'
  15. import { ssoAvailableForInstitution } from '../../../utils/sso'
  16. const getDescription = (
  17. t: (s: string) => string,
  18. state: State,
  19. userEmailData: UserEmailData
  20. ) => {
  21. if (inReconfirmNotificationPeriod(userEmailData)) {
  22. return t('please_reconfirm_your_affiliation_before_making_this_primary')
  23. }
  24. if (userEmailData.confirmedAt) {
  25. return t('make_email_primary_description')
  26. }
  27. const ssoAvailable = ssoAvailableForInstitution(
  28. userEmailData.affiliation?.institution || null
  29. )
  30. if (!institutionAlreadyLinked(state, userEmailData) && ssoAvailable) {
  31. return t('please_link_before_making_primary')
  32. }
  33. return t('please_confirm_your_email_before_making_it_default')
  34. }
  35. function PrimaryButton({ children, disabled, onClick }: Button.ButtonProps) {
  36. return (
  37. <Button
  38. bsSize="small"
  39. bsStyle={null}
  40. className="btn-secondary-info btn-secondary"
  41. disabled={disabled}
  42. onClick={onClick}
  43. >
  44. {children}
  45. </Button>
  46. )
  47. }
  48. type MakePrimaryProps = {
  49. userEmailData: UserEmailData
  50. makePrimaryAsync: UseAsyncReturnType
  51. }
  52. function MakePrimary({ userEmailData, makePrimaryAsync }: MakePrimaryProps) {
  53. const { t } = useTranslation()
  54. const { state, makePrimary } = useUserEmailsContext()
  55. const handleSetDefaultUserEmail = () => {
  56. makePrimaryAsync
  57. .runAsync(
  58. postJSON('/user/emails/default', {
  59. body: {
  60. email: userEmailData.email,
  61. },
  62. })
  63. )
  64. .then(() => {
  65. makePrimary(userEmailData.email)
  66. })
  67. .catch(() => {})
  68. }
  69. if (userEmailData.default) {
  70. return null
  71. }
  72. if (makePrimaryAsync.isLoading) {
  73. return <PrimaryButton disabled>{t('sending')}...</PrimaryButton>
  74. }
  75. return (
  76. <Tooltip
  77. id={`make-primary-${userEmailData.email}`}
  78. description={getDescription(t, state, userEmailData)}
  79. >
  80. {/*
  81. Disabled buttons don't work with tooltips, due to pointer-events: none,
  82. so create a wrapper for the tooltip
  83. */}
  84. <span>
  85. <PrimaryButton
  86. disabled={
  87. !userEmailData.confirmedAt ||
  88. state.isLoading ||
  89. inReconfirmNotificationPeriod(userEmailData)
  90. }
  91. onClick={handleSetDefaultUserEmail}
  92. >
  93. {t('make_primary')}
  94. </PrimaryButton>
  95. </span>
  96. </Tooltip>
  97. )
  98. }
  99. export default MakePrimary