row.tsx 4.9 KB

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