row.tsx 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. import { useState } from 'react'
  2. import { Trans, useTranslation } from 'react-i18next'
  3. import { UserEmailData } from '../../../../../../types/user-email'
  4. import { Button, Row, Col } from 'react-bootstrap'
  5. import Email from './email'
  6. import InstitutionAndRole from './institution-and-role'
  7. import EmailCell from './cell'
  8. import Actions from './actions'
  9. import { institutionAlreadyLinked } from '../../utils/selectors'
  10. import { useUserEmailsContext } from '../../context/user-email-context'
  11. import getMeta from '../../../../utils/meta'
  12. import { ExposedSettings } from '../../../../../../types/exposed-settings'
  13. import { ssoAvailableForInstitution } from '../../utils/sso'
  14. import ReconfirmationInfo from './reconfirmation-info'
  15. import { useLocation } from '../../../../shared/hooks/use-location'
  16. type EmailsRowProps = {
  17. userEmailData: UserEmailData
  18. }
  19. function EmailsRow({ userEmailData }: EmailsRowProps) {
  20. const hasSSOAffiliation = Boolean(
  21. userEmailData.affiliation &&
  22. ssoAvailableForInstitution(userEmailData.affiliation.institution)
  23. )
  24. return (
  25. <>
  26. <Row>
  27. <Col md={4}>
  28. <EmailCell>
  29. <Email userEmailData={userEmailData} />
  30. </EmailCell>
  31. </Col>
  32. <Col md={5}>
  33. {userEmailData.affiliation?.institution && (
  34. <EmailCell>
  35. <InstitutionAndRole userEmailData={userEmailData} />
  36. </EmailCell>
  37. )}
  38. </Col>
  39. <Col md={3}>
  40. <EmailCell className="text-md-right">
  41. <Actions userEmailData={userEmailData} />
  42. </EmailCell>
  43. </Col>
  44. </Row>
  45. {hasSSOAffiliation && (
  46. <SSOAffiliationInfo userEmailData={userEmailData} />
  47. )}
  48. <ReconfirmationInfo userEmailData={userEmailData} />
  49. </>
  50. )
  51. }
  52. type SSOAffiliationInfoProps = {
  53. userEmailData: UserEmailData
  54. }
  55. function SSOAffiliationInfo({ userEmailData }: SSOAffiliationInfoProps) {
  56. const { samlInitPath } = getMeta('ol-ExposedSettings') as ExposedSettings
  57. const { t } = useTranslation()
  58. const { state } = useUserEmailsContext()
  59. const location = useLocation()
  60. const [linkAccountsButtonDisabled, setLinkAccountsButtonDisabled] =
  61. useState(false)
  62. function handleLinkAccountsButtonClick() {
  63. setLinkAccountsButtonDisabled(true)
  64. location.assign(
  65. `${samlInitPath}?university_id=${userEmailData.affiliation?.institution?.id}&auto=/user/settings&email=${userEmailData.email}`
  66. )
  67. }
  68. if (
  69. !userEmailData.samlProviderId &&
  70. institutionAlreadyLinked(state, userEmailData)
  71. ) {
  72. // if the email is not linked to the institution, but there's another email already linked to that institution
  73. // no SSO affiliation is displayed, since cannot have multiple emails linked to the same institution
  74. return null
  75. }
  76. if (userEmailData.samlProviderId) {
  77. return (
  78. <Row>
  79. <Col md={8} mdOffset={4}>
  80. <EmailCell>
  81. <p>
  82. <Trans
  83. i18nKey="acct_linked_to_institution_acct_2"
  84. components={
  85. /* eslint-disable-next-line jsx-a11y/anchor-has-content, react/jsx-key */
  86. [<strong />]
  87. }
  88. values={{
  89. institutionName: userEmailData.affiliation?.institution.name,
  90. }}
  91. />
  92. </p>
  93. </EmailCell>
  94. </Col>
  95. </Row>
  96. )
  97. }
  98. return (
  99. <Row>
  100. <Col md={8} mdOffset={4}>
  101. <div className="horizontal-divider" />
  102. <Row>
  103. <Col md={9}>
  104. <EmailCell>
  105. <p className="small">
  106. <Trans
  107. i18nKey="can_link_your_institution_acct_2"
  108. values={{
  109. institutionName:
  110. userEmailData.affiliation?.institution.name,
  111. }}
  112. components={
  113. /* eslint-disable-next-line jsx-a11y/anchor-has-content, react/jsx-key */
  114. [<strong />]
  115. }
  116. />
  117. </p>
  118. <p className="small">
  119. <Trans
  120. i18nKey="doing_this_allow_log_in_through_institution_2"
  121. components={
  122. /* eslint-disable-next-line jsx-a11y/anchor-has-content, react/jsx-key */
  123. [<strong />]
  124. }
  125. />{' '}
  126. <a href="/learn/how-to/Institutional_Login">
  127. {t('find_out_more_about_institution_login')}
  128. </a>
  129. </p>
  130. </EmailCell>
  131. </Col>
  132. <Col md={3} className="text-md-right">
  133. <EmailCell>
  134. <Button
  135. bsStyle="primary"
  136. className="btn-sm btn-link-accounts"
  137. disabled={linkAccountsButtonDisabled}
  138. onClick={handleLinkAccountsButtonClick}
  139. >
  140. {t('link_accounts')}
  141. </Button>
  142. </EmailCell>
  143. </Col>
  144. </Row>
  145. </Col>
  146. </Row>
  147. )
  148. }
  149. export default EmailsRow