mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-07 20:31:06 -05:00
e5051bcd1d
Add email with existing and non existing institution GitOrigin-RevId: 331bc06f0ea289a82b403a910491e233f4eda4bb
247 lines
7.6 KiB
TypeScript
247 lines
7.6 KiB
TypeScript
import { useState, useEffect } from 'react'
|
|
import { useTranslation } from 'react-i18next'
|
|
import { Button, Row, Col } from 'react-bootstrap'
|
|
import Cell from './cell'
|
|
import Icon from '../../../../shared/components/icon'
|
|
import DownshiftInput from './downshift-input'
|
|
import CountryInput from './country-input'
|
|
import { AddEmailInput } from './add-email-input'
|
|
import useAsync from '../../../../shared/hooks/use-async'
|
|
import { useUserEmailsContext } from '../../context/user-email-context'
|
|
import { getJSON, postJSON } from '../../../../infrastructure/fetch-json'
|
|
import { defaults as roles } from '../../roles'
|
|
import { defaults as departments } from '../../departments'
|
|
import { University } from '../../../../../../types/university'
|
|
import { CountryCode } from '../../../../../../types/country'
|
|
|
|
const isValidEmail = (email: string) => {
|
|
return Boolean(email)
|
|
}
|
|
|
|
function AddEmail() {
|
|
const { t } = useTranslation()
|
|
const [isFormVisible, setIsFormVisible] = useState(
|
|
() => window.location.hash === '#add-email'
|
|
)
|
|
const [newEmail, setNewEmail] = useState('')
|
|
const [countryCode, setCountryCode] = useState<CountryCode | null>(null)
|
|
const [universities, setUniversities] = useState<
|
|
Partial<Record<CountryCode, University[]>>
|
|
>({})
|
|
const [university, setUniversity] = useState('')
|
|
const [role, setRole] = useState('')
|
|
const [department, setDepartment] = useState('')
|
|
const [isInstitutionFieldsVisible, setIsInstitutionFieldsVisible] =
|
|
useState(false)
|
|
const [isUniversityDirty, setIsUniversityDirty] = useState(false)
|
|
const { isLoading, isError, runAsync } = useAsync()
|
|
const { runAsync: institutionRunAsync } = useAsync()
|
|
const {
|
|
state,
|
|
setLoading: setUserEmailsContextLoading,
|
|
getEmails,
|
|
} = useUserEmailsContext()
|
|
|
|
useEffect(() => {
|
|
setUserEmailsContextLoading(isLoading)
|
|
}, [setUserEmailsContextLoading, isLoading])
|
|
|
|
useEffect(() => {
|
|
if (university) {
|
|
setIsUniversityDirty(true)
|
|
}
|
|
}, [setIsUniversityDirty, university])
|
|
|
|
// Fetch country institution
|
|
useEffect(() => {
|
|
// Skip if country not selected or universities for
|
|
// that country are already fetched
|
|
if (!countryCode || universities[countryCode]) {
|
|
return
|
|
}
|
|
|
|
institutionRunAsync<University[]>(
|
|
getJSON(`/institutions/list?country_code=${countryCode}`)
|
|
)
|
|
.then(data => {
|
|
setUniversities(state => ({ ...state, [countryCode]: data }))
|
|
})
|
|
.catch(() => {})
|
|
}, [countryCode, universities, setUniversities, institutionRunAsync])
|
|
|
|
const handleShowAddEmailForm = () => {
|
|
setIsFormVisible(true)
|
|
}
|
|
|
|
const handleShowInstitutionFields = () => {
|
|
setIsInstitutionFieldsVisible(true)
|
|
}
|
|
|
|
const handleEmailChange = (value: string) => {
|
|
setNewEmail(value)
|
|
}
|
|
|
|
const handleAddNewEmail = () => {
|
|
const selectedKnownUniversity = countryCode
|
|
? universities[countryCode]?.find(({ name }) => name === university)
|
|
: undefined
|
|
|
|
const knownUniversityData = university &&
|
|
selectedKnownUniversity && {
|
|
university: {
|
|
id: selectedKnownUniversity.id,
|
|
},
|
|
role,
|
|
department,
|
|
}
|
|
|
|
const unknownUniversityData = university &&
|
|
!selectedKnownUniversity && {
|
|
university: {
|
|
name: university,
|
|
country_code: countryCode,
|
|
},
|
|
role,
|
|
department,
|
|
}
|
|
|
|
runAsync(
|
|
postJSON('/user/emails', {
|
|
body: {
|
|
email: newEmail,
|
|
...knownUniversityData,
|
|
...unknownUniversityData,
|
|
},
|
|
})
|
|
)
|
|
.then(() => {
|
|
getEmails()
|
|
setIsFormVisible(false)
|
|
setNewEmail('')
|
|
setCountryCode(null)
|
|
setIsUniversityDirty(false)
|
|
setUniversity('')
|
|
setRole('')
|
|
setDepartment('')
|
|
setIsInstitutionFieldsVisible(false)
|
|
})
|
|
.catch(() => {})
|
|
}
|
|
|
|
const getUniversityItems = () => {
|
|
if (!countryCode) {
|
|
return []
|
|
}
|
|
|
|
return universities[countryCode]?.map(({ name }) => name) ?? []
|
|
}
|
|
|
|
return (
|
|
<div className="affiliations-table-row--highlighted">
|
|
<Row>
|
|
{!isFormVisible ? (
|
|
<Col md={4}>
|
|
<Cell>
|
|
<Button
|
|
className="btn-inline-link"
|
|
onClick={handleShowAddEmailForm}
|
|
>
|
|
{t('add_another_email')}
|
|
</Button>
|
|
</Cell>
|
|
</Col>
|
|
) : (
|
|
<form>
|
|
<Col md={4}>
|
|
<Cell>
|
|
<label htmlFor="affiliations-email" className="sr-only">
|
|
{t('email')}
|
|
</label>
|
|
<AddEmailInput onChange={handleEmailChange} />
|
|
</Cell>
|
|
</Col>
|
|
<Col md={4}>
|
|
<Cell>
|
|
{isInstitutionFieldsVisible ? (
|
|
<>
|
|
<div className="form-group mb-2">
|
|
<CountryInput
|
|
id="new-email-country-input"
|
|
setValue={setCountryCode}
|
|
/>
|
|
</div>
|
|
<div className="form-group mb-2">
|
|
<DownshiftInput
|
|
items={getUniversityItems()}
|
|
inputValue={university}
|
|
placeholder={t('university')}
|
|
label={t('university')}
|
|
setValue={setUniversity}
|
|
disabled={!countryCode}
|
|
/>
|
|
</div>
|
|
{isUniversityDirty && (
|
|
<>
|
|
<div className="form-group mb-2">
|
|
<DownshiftInput
|
|
items={roles}
|
|
inputValue={role}
|
|
placeholder={t('role')}
|
|
label={t('role')}
|
|
setValue={setRole}
|
|
/>
|
|
</div>
|
|
<div className="form-group mb-0">
|
|
<DownshiftInput
|
|
items={departments}
|
|
inputValue={department}
|
|
placeholder={t('department')}
|
|
label={t('department')}
|
|
setValue={setDepartment}
|
|
/>
|
|
</div>
|
|
</>
|
|
)}
|
|
</>
|
|
) : (
|
|
<div className="mt-1">
|
|
{t('is_email_affiliated')}
|
|
<br />
|
|
<Button
|
|
className="btn-inline-link"
|
|
onClick={handleShowInstitutionFields}
|
|
>
|
|
{t('let_us_know')}
|
|
</Button>
|
|
</div>
|
|
)}
|
|
</Cell>
|
|
</Col>
|
|
<Col md={4}>
|
|
<Cell className="text-md-right">
|
|
<Button
|
|
bsSize="small"
|
|
bsStyle="success"
|
|
disabled={
|
|
!isValidEmail(newEmail) || isLoading || state.isLoading
|
|
}
|
|
onClick={handleAddNewEmail}
|
|
>
|
|
{t('add_new_email')}
|
|
</Button>
|
|
{isError && (
|
|
<div className="text-danger small">
|
|
<Icon type="exclamation-triangle" fw />{' '}
|
|
{t('error_performing_request')}
|
|
</div>
|
|
)}
|
|
</Cell>
|
|
</Col>
|
|
</form>
|
|
)}
|
|
</Row>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default AddEmail
|