make-primary.tsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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 bsSize="small" bsStyle="info" disabled={disabled} onClick={onClick}>
  38. {children}
  39. </Button>
  40. )
  41. }
  42. type MakePrimaryProps = {
  43. userEmailData: UserEmailData
  44. makePrimaryAsync: UseAsyncReturnType
  45. }
  46. function MakePrimary({ userEmailData, makePrimaryAsync }: MakePrimaryProps) {
  47. const { t } = useTranslation()
  48. const { state, makePrimary } = useUserEmailsContext()
  49. const handleSetDefaultUserEmail = () => {
  50. makePrimaryAsync
  51. .runAsync(
  52. postJSON('/user/emails/default', {
  53. body: {
  54. email: userEmailData.email,
  55. },
  56. })
  57. )
  58. .then(() => {
  59. makePrimary(userEmailData.email)
  60. })
  61. .catch(() => {})
  62. }
  63. if (userEmailData.default) {
  64. return null
  65. }
  66. if (makePrimaryAsync.isLoading) {
  67. return <PrimaryButton disabled>{t('sending')}...</PrimaryButton>
  68. }
  69. return (
  70. <Tooltip
  71. id={`make-primary-${userEmailData.email}`}
  72. description={getDescription(t, state, userEmailData)}
  73. >
  74. {/*
  75. Disabled buttons don't work with tooltips, due to pointer-events: none,
  76. so create a wrapper for the tooltip
  77. */}
  78. <span>
  79. <PrimaryButton
  80. disabled={
  81. !userEmailData.confirmedAt ||
  82. state.isLoading ||
  83. inReconfirmNotificationPeriod(userEmailData)
  84. }
  85. onClick={handleSetDefaultUserEmail}
  86. >
  87. {t('make_primary')}
  88. </PrimaryButton>
  89. </span>
  90. </Tooltip>
  91. )
  92. }
  93. export default MakePrimary