Skip to content
Snippets Groups Projects
Commit cce76605 authored by Tore.Brede's avatar Tore.Brede
Browse files

Moving register component to be under sponsor

parent 2d98b5b3
No related branches found
No related tags found
1 merge request!109Refactor register summary step
Pipeline #96982 passed
......@@ -8,7 +8,7 @@ import fetchIntercept from 'fetch-intercept'
import { useUserContext } from 'contexts'
import Sponsor from 'routes/sponsor'
import Register from 'routes/register'
import Register from 'routes/sponsor/register'
import FrontPage from 'routes/frontpage'
import Invite from 'routes/invite'
import InviteLink from 'routes/invitelink'
......
import {
Box,
FormControl,
InputLabel,
MenuItem,
Select,
SelectChangeEvent,
Stack,
TextField,
Typography,
} from '@mui/material'
import { Controller, SubmitHandler, useForm } from 'react-hook-form'
import { DatePicker } from '@mui/lab'
import React, { forwardRef, Ref, useEffect, useImperativeHandle, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { RegisterFormData } from './formData'
import { PersonFormMethods } from './personFormMethods'
import useOus, { OuData } from '../../hooks/useOus'
import useRoleTypes, { RoleTypeData } from '../../hooks/useRoleTypes'
import { isValidEmail } from '../../utils'
interface StepPersonFormProperties {
nextHandler(formState: RegisterFormData): void
formData: RegisterFormData
}
const StepPersonForm = forwardRef((props: StepPersonFormProperties, ref: Ref<PersonFormMethods>) => {
const { i18n, t } = useTranslation(['common'])
const { nextHandler, formData } = props
const ous = useOus()
const [ouChoice, setOuChoice] = useState(formData.ou_id ? formData.ou_id : '')
const [selectedRoleType, setSelectedRoleType] = useState(formData.role_type ? formData.role_type : '')
const roleTypes = useRoleTypes()
const roleTypeSort = () => (a: RoleTypeData, b: RoleTypeData) => {
if (i18n.language === 'en') {
return a.name_nb.localeCompare(b.name_nb)
}
return a.name_en.localeCompare(b.name_en)
}
const enSort = (a: OuData, b: OuData) => {
if (a.en > b.en) {
return 1
}
if (b.en > a.en) {
return -1
}
return 0
}
const nbSort = (a: OuData, b: OuData) => {
if (a.nb > b.nb) {
return 1
}
if (b.nb > a.nb) {
return -1
}
return 0
}
const submit: SubmitHandler<RegisterFormData> = (data) => {
nextHandler(data)
}
const {
register,
control,
handleSubmit,
formState: { errors },
reset,
setValue,
} = useForm<RegisterFormData>()
const onSubmit = handleSubmit(submit)
useEffect(() => {
reset(formData)
}, [])
const handleOuChange = (event: SelectChangeEvent) => {
if (event.target.value) {
setOuChoice(event.target.value)
setValue('ou_id', parseInt(event.target.value, 10))
} else {
setValue('ou_id', undefined)
}
}
register('role_type', {
required: t<string>('validation.roleTypeRequired'),
})
const handleRoleTypeChange = (event: any) => {
setValue('role_type', event.target.value)
setSelectedRoleType(event.target.value)
}
function doSubmit() {
return onSubmit()
}
useImperativeHandle(ref, () => ({ doSubmit }))
return (
<>
<Typography variant='h5' sx={{
paddingTop: '1rem',
paddingBottom: '1rem',
}}>{t('registerWizardText.registerContactInfo')}</Typography>
<Typography sx={{ paddingBottom: '2rem' }}>{t('registerWizardText.registerPage')}</Typography>
<Box sx={{ maxWidth: '30rem' }}>
<form onSubmit={onSubmit}>
<Stack spacing={2}>
<TextField
id='firstName'
label={t('input.firstName')}
error={!!errors.first_name}
helperText={errors.first_name && errors.first_name.message}
{...register(`first_name`, {
required: t<string>('validation.firstNameRequired'),
})}
/>
<TextField
id='lastName'
label={t('input.lastName')}
error={!!errors.last_name}
helperText={errors.last_name && errors.last_name.message}
{...register(`last_name`, {
required: t<string>('validation.lastNameRequired'),
})}
/>
<TextField
id='email'
label={t('input.email')}
error={!!errors.email}
helperText={errors.email && errors.email.message}
{...register(`email`, {
validate: isValidEmail,
})}
/>
<Typography variant='h5' sx={{ paddingTop: '1rem' }}>{t('registerWizardText.registerPeriod')}</Typography>
<Typography sx={{ paddingBottom: '1rem' }}>{t('registerWizardText.registerPeriodText')}</Typography>
<FormControl fullWidth>
<InputLabel id='ou-select-label'>{t('common:ou')}</InputLabel>
<Select
labelId='ou-select-label'
id='ou-select-label'
value={ouChoice?.toString()}
label={t('common:ou')}
onChange={handleOuChange}
>
{ous.length > 0 ? (
ous
.sort(i18n.language === 'en' ? enSort : nbSort)
.map((ou) => (
<MenuItem key={ou.id.toString()} value={ou.id}>
{i18n.language === 'en' ? ou.en : ou.nb} ({ou.id})
</MenuItem>
))
) : (
<></>
)}
</Select>
</FormControl>
<TextField
id='roletype-select'
select
value={selectedRoleType}
error={!!errors.role_type}
label={t('input.roleType')}
onChange={handleRoleTypeChange}
>
{
roleTypes.sort(roleTypeSort())
.map((roleType) => (
<MenuItem
key={roleType.id.toString()}
value={roleType.id}>{i18n.language === 'en' ? roleType.name_en : roleType.name_nb}</MenuItem>
))
}
</TextField>
<Controller name='role_start'
control={control}
render={({ field }) => (
<DatePicker
mask='____-__-__'
label={t('input.roleStartDate')}
value={field.value}
inputFormat='yyyy-MM-dd'
onChange={(value) => {
field.onChange(value)
}}
renderInput={(params) => <TextField {...params} />}
/>)}
/>
<Controller name='role_end'
control={control}
defaultValue={undefined}
render={({ field }) => (
<DatePicker
mask='____-__-__'
label={t('input.roleEndDate')}
value={field.value}
inputFormat='yyyy-MM-dd'
onChange={(value) => {
field.onChange(value)
}}
renderInput={(params) => <TextField {...params} />}
/>)}
/>
<TextField
id='comment'
label={t('input.comment')}
multiline
rows={5}
{...register(`comment`)}
/>
</Stack>
</form>
</Box>
</>
)
})
export default StepPersonForm
import React, { forwardRef } from 'react'
import { useTranslation } from 'react-i18next'
import {
Box,
Grid,
Table,
TableBody,
TableCell,
TableHead,
TableRow,
} from '@mui/material'
import format from 'date-fns/format'
import i18n from 'i18next'
import { RegisterFormData } from './formData'
import useOus from '../../hooks/useOus'
import useRoleTypes from '../../hooks/useRoleTypes'
interface StepSummaryProperties {
formData: RegisterFormData
}
const StepSummary = forwardRef((props: StepSummaryProperties) => {
const { t } = useTranslation(['common'])
const { formData } = props
const ous = useOus()
const roleTypes = useRoleTypes()
const selectedOus = ous.find((value) => value.id === formData.ou_id)
const ousName = selectedOus === undefined ? '' : (`${i18n.language === 'en' ? selectedOus.en : selectedOus.nb} (${selectedOus.id})`)
// TODO Fix this confusing mix between use of id and identifier
const selectedRoleType = roleTypes.find((value) => value.id === (formData.role_type === undefined ? -1 : parseInt(formData.role_type, 10)))
const roleTypeName = selectedRoleType === undefined ? '' : `${i18n.language === 'en' ? selectedRoleType.name_en : selectedRoleType.name_nb}`
return (
<>
<Box sx={{
paddingTop: '1rem',
paddingBottom: '1rem',
}}>
{t('registerWizardText.summaryContactInformation')}
</Box>
<Box sx={{ typography: 'body2' }}>
{t('registerWizardText.summaryPage')}
</Box>
<Box sx={{ marginTop: '1rem', maxWidth: '50rem' }}>
<Box sx={{
typography: 'subtitle2',
marginBottom: '0.5rem',
paddingLeft: '0.5rem',
bgcolor: 'primary.light',
}}>{t('registerWizardText.contactInformation')}</Box>
<Grid sx={{ typography: 'body2', paddingLeft: '0.5rem' }} container>
<Grid item xs={4}>
{t('input.fullName')}
</Grid>
<Grid item xs={8}>
{formData.first_name} {formData.last_name}
</Grid>
<Grid item xs={4}>
{t('input.email')}
</Grid>
<Grid item xs={8}>
{formData.email}
</Grid>
</Grid>
<Box sx={{
paddingTop: '1rem',
paddingBottom: '1rem',
}}>
{t('registerWizardText.summaryPeriod')}
</Box>
<Table>
<TableHead sx={{
paddingLeft: '0.5rem',
bgcolor: 'primary.light',
}}>
<TableRow>
<TableCell>{t('registerWizardText.guestRole')}</TableCell>
<TableCell>{t('registerWizardText.guestPeriod')}</TableCell>
<TableCell>{t('registerWizardText.guestDepartment')}</TableCell>
<TableCell>{t('input.comment')}</TableCell>
</TableRow>
</TableHead>
<TableBody>
<TableRow>
<TableCell>{roleTypeName}</TableCell>
<TableCell>{formData.role_start === null ? null : format(formData.role_start as Date, 'yyyy-MM-dd')} - {formData.role_end === null ? null : format(formData.role_end as Date, 'yyyy-MM-dd')}</TableCell>
<TableCell>{ousName}</TableCell>
<TableCell>{formData.comment}</TableCell>
</TableRow>
</TableBody>
</Table>
</Box>
</>
)
},
)
export default StepSummary
......@@ -11,9 +11,8 @@ import StepSummary from './stepSummary'
import StepPersonForm from './stepPersonForm'
import { PersonFormMethods } from './personFormMethods'
import SubmitState from './submitState'
import SponsorGuestButtons from '../components/sponsorGuestButtons'
import { postJsonOpts } from '../../utils'
import SponsorGuestButtons from '../../components/sponsorGuestButtons'
import { postJsonOpts } from '../../../utils'
/**
*
......@@ -41,7 +40,6 @@ export default function StepRegistration() {
const personFormRef = useRef<PersonFormMethods>(null)
const [submitState, setSubmitState] = useState(SubmitState.NotSubmitted)
const handleNext = () => {
if (activeStep === 0) {
if (personFormRef.current) {
......@@ -59,8 +57,14 @@ export default function StepRegistration() {
email: formData.email,
role: {
type: formData.role_type,
start_date: formData.role_start === null ? null : format(formData.role_start as Date, 'yyyy-MM-dd'),
end_date: formData.role_end === null ? null : format(formData.role_end as Date, 'yyyy-MM-dd'),
start_date:
formData.role_start === null
? null
: format(formData.role_start as Date, 'yyyy-MM-dd'),
end_date:
formData.role_end === null
? null
: format(formData.role_end as Date, 'yyyy-MM-dd'),
comments: formData.comment,
orgunit_id: formData.ou_id,
},
......@@ -92,7 +96,7 @@ export default function StepRegistration() {
}
const handleForwardFromRegister = (
updateFormData: RegisterFormData,
updateFormData: RegisterFormData
): void => {
setFormData(updateFormData)
setActiveStep((prevActiveStep) => prevActiveStep + 1)
......@@ -114,18 +118,24 @@ export default function StepRegistration() {
ref={personFormRef}
/>
)}
{activeStep === SUMMARY_STEP && (
<StepSummary
formData={formData}
/>
)}
{activeStep === SUMMARY_STEP && <StepSummary formData={formData} />}
</Box>
<Box sx={{ display: 'flex', flexDirection: 'row', pt: 2, color: 'primary.main', paddingBottom: '1rem' }}>
<Box
sx={{
display: 'flex',
flexDirection: 'row',
pt: 2,
color: 'primary.main',
paddingBottom: '1rem',
}}
>
{activeStep === REGISTER_STEP && (
<Button data-testid='button-next'
sx={{ color: 'theme.palette.secondary', mr: 1 }}
onClick={handleNext}>
<Button
data-testid="button-next"
sx={{ color: 'theme.palette.secondary', mr: 1 }}
onClick={handleNext}
>
{t('button.next')}
</Button>
)}
......@@ -170,7 +180,6 @@ export default function StepRegistration() {
<h2>Submit failure</h2>
</Box>
)}
</Page>
)
}
import {
Box,
FormControl,
InputLabel,
MenuItem,
Select,
SelectChangeEvent,
Stack,
TextField,
Typography,
} from '@mui/material'
import { Controller, SubmitHandler, useForm } from 'react-hook-form'
import { DatePicker } from '@mui/lab'
import React, {
forwardRef,
Ref,
useEffect,
useImperativeHandle,
useState,
} from 'react'
import { useTranslation } from 'react-i18next'
import { RegisterFormData } from './formData'
import { PersonFormMethods } from './personFormMethods'
import useOus, { OuData } from '../../../hooks/useOus'
import useRoleTypes, { RoleTypeData } from '../../../hooks/useRoleTypes'
import { isValidEmail } from '../../../utils'
interface StepPersonFormProperties {
nextHandler(formState: RegisterFormData): void
formData: RegisterFormData
}
const StepPersonForm = forwardRef(
(props: StepPersonFormProperties, ref: Ref<PersonFormMethods>) => {
const { i18n, t } = useTranslation(['common'])
const { nextHandler, formData } = props
const ous = useOus()
const [ouChoice, setOuChoice] = useState(
formData.ou_id ? formData.ou_id : ''
)
const [selectedRoleType, setSelectedRoleType] = useState(
formData.role_type ? formData.role_type : ''
)
const roleTypes = useRoleTypes()
const roleTypeSort = () => (a: RoleTypeData, b: RoleTypeData) => {
if (i18n.language === 'en') {
return a.name_nb.localeCompare(b.name_nb)
}
return a.name_en.localeCompare(b.name_en)
}
const enSort = (a: OuData, b: OuData) => {
if (a.en > b.en) {
return 1
}
if (b.en > a.en) {
return -1
}
return 0
}
const nbSort = (a: OuData, b: OuData) => {
if (a.nb > b.nb) {
return 1
}
if (b.nb > a.nb) {
return -1
}
return 0
}
const submit: SubmitHandler<RegisterFormData> = (data) => {
nextHandler(data)
}
const {
register,
control,
handleSubmit,
formState: { errors },
reset,
setValue,
} = useForm<RegisterFormData>()
const onSubmit = handleSubmit(submit)
useEffect(() => {
reset(formData)
}, [])
const handleOuChange = (event: SelectChangeEvent) => {
if (event.target.value) {
setOuChoice(event.target.value)
setValue('ou_id', parseInt(event.target.value, 10))
} else {
setValue('ou_id', undefined)
}
}
register('role_type', {
required: t<string>('validation.roleTypeRequired'),
})
const handleRoleTypeChange = (event: any) => {
setValue('role_type', event.target.value)
setSelectedRoleType(event.target.value)
}
function doSubmit() {
return onSubmit()
}
useImperativeHandle(ref, () => ({ doSubmit }))
return (
<>
<Typography
variant="h5"
sx={{
paddingTop: '1rem',
paddingBottom: '1rem',
}}
>
{t('registerWizardText.registerContactInfo')}
</Typography>
<Typography sx={{ paddingBottom: '2rem' }}>
{t('registerWizardText.registerPage')}
</Typography>
<Box sx={{ maxWidth: '30rem' }}>
<form onSubmit={onSubmit}>
<Stack spacing={2}>
<TextField
id="firstName"
label={t('input.firstName')}
error={!!errors.first_name}
helperText={errors.first_name && errors.first_name.message}
{...register(`first_name`, {
required: t<string>('validation.firstNameRequired'),
})}
/>
<TextField
id="lastName"
label={t('input.lastName')}
error={!!errors.last_name}
helperText={errors.last_name && errors.last_name.message}
{...register(`last_name`, {
required: t<string>('validation.lastNameRequired'),
})}
/>
<TextField
id="email"
label={t('input.email')}
error={!!errors.email}
helperText={errors.email && errors.email.message}
{...register(`email`, {
validate: isValidEmail,
})}
/>
<Typography variant="h5" sx={{ paddingTop: '1rem' }}>
{t('registerWizardText.registerPeriod')}
</Typography>
<Typography sx={{ paddingBottom: '1rem' }}>
{t('registerWizardText.registerPeriodText')}
</Typography>
<FormControl fullWidth>
<InputLabel id="ou-select-label">{t('common:ou')}</InputLabel>
<Select
labelId="ou-select-label"
id="ou-select-label"
value={ouChoice?.toString()}
label={t('common:ou')}
onChange={handleOuChange}
>
{ous.length > 0 ? (
ous
.sort(i18n.language === 'en' ? enSort : nbSort)
.map((ou) => (
<MenuItem key={ou.id.toString()} value={ou.id}>
{i18n.language === 'en' ? ou.en : ou.nb} ({ou.id})
</MenuItem>
))
) : (
<></>
)}
</Select>
</FormControl>
<TextField
id="roletype-select"
select
value={selectedRoleType}
error={!!errors.role_type}
label={t('input.roleType')}
onChange={handleRoleTypeChange}
>
{roleTypes.sort(roleTypeSort()).map((roleType) => (
<MenuItem key={roleType.id.toString()} value={roleType.id}>
{i18n.language === 'en'
? roleType.name_en
: roleType.name_nb}
</MenuItem>
))}
</TextField>
<Controller
name="role_start"
control={control}
render={({ field }) => (
<DatePicker
mask="____-__-__"
label={t('input.roleStartDate')}
value={field.value}
inputFormat="yyyy-MM-dd"
onChange={(value) => {
field.onChange(value)
}}
renderInput={(params) => <TextField {...params} />}
/>
)}
/>
<Controller
name="role_end"
control={control}
defaultValue={undefined}
render={({ field }) => (
<DatePicker
mask="____-__-__"
label={t('input.roleEndDate')}
value={field.value}
inputFormat="yyyy-MM-dd"
onChange={(value) => {
field.onChange(value)
}}
renderInput={(params) => <TextField {...params} />}
/>
)}
/>
<TextField
id="comment"
label={t('input.comment')}
multiline
rows={5}
{...register(`comment`)}
/>
</Stack>
</form>
</Box>
</>
)
}
)
export default StepPersonForm
import React, { forwardRef } from 'react'
import { useTranslation } from 'react-i18next'
import {
Box,
Grid,
Table,
TableBody,
TableCell,
TableHead,
TableRow,
} from '@mui/material'
import format from 'date-fns/format'
import i18n from 'i18next'
import { RegisterFormData } from './formData'
import useOus from '../../../hooks/useOus'
import useRoleTypes from '../../../hooks/useRoleTypes'
interface StepSummaryProperties {
formData: RegisterFormData
}
const StepSummary = forwardRef((props: StepSummaryProperties) => {
const { t } = useTranslation(['common'])
const { formData } = props
const ous = useOus()
const roleTypes = useRoleTypes()
const selectedOus = ous.find((value) => value.id === formData.ou_id)
const ousName =
selectedOus === undefined
? ''
: `${i18n.language === 'en' ? selectedOus.en : selectedOus.nb} (${
selectedOus.id
})`
// TODO Fix this confusing mix between use of id and identifier
const selectedRoleType = roleTypes.find(
(value) =>
value.id ===
(formData.role_type === undefined ? -1 : parseInt(formData.role_type, 10))
)
const roleTypeName =
selectedRoleType === undefined
? ''
: `${
i18n.language === 'en'
? selectedRoleType.name_en
: selectedRoleType.name_nb
}`
return (
<>
<Box
sx={{
paddingTop: '1rem',
paddingBottom: '1rem',
}}
>
{t('registerWizardText.summaryContactInformation')}
</Box>
<Box sx={{ typography: 'body2' }}>
{t('registerWizardText.summaryPage')}
</Box>
<Box sx={{ marginTop: '1rem', maxWidth: '50rem' }}>
<Box
sx={{
typography: 'subtitle2',
marginBottom: '0.5rem',
paddingLeft: '0.5rem',
bgcolor: 'primary.light',
}}
>
{t('registerWizardText.contactInformation')}
</Box>
<Grid sx={{ typography: 'body2', paddingLeft: '0.5rem' }} container>
<Grid item xs={4}>
{t('input.fullName')}
</Grid>
<Grid item xs={8}>
{formData.first_name} {formData.last_name}
</Grid>
<Grid item xs={4}>
{t('input.email')}
</Grid>
<Grid item xs={8}>
{formData.email}
</Grid>
</Grid>
<Box
sx={{
paddingTop: '1rem',
paddingBottom: '1rem',
}}
>
{t('registerWizardText.summaryPeriod')}
</Box>
<Table>
<TableHead
sx={{
paddingLeft: '0.5rem',
bgcolor: 'primary.light',
}}
>
<TableRow>
<TableCell>{t('registerWizardText.guestRole')}</TableCell>
<TableCell>{t('registerWizardText.guestPeriod')}</TableCell>
<TableCell>{t('registerWizardText.guestDepartment')}</TableCell>
<TableCell>{t('input.comment')}</TableCell>
</TableRow>
</TableHead>
<TableBody>
<TableRow>
<TableCell>{roleTypeName}</TableCell>
<TableCell>
{formData.role_start === null
? null
: format(formData.role_start as Date, 'yyyy-MM-dd')}{' '}
-{' '}
{formData.role_end === null
? null
: format(formData.role_end as Date, 'yyyy-MM-dd')}
</TableCell>
<TableCell>{ousName}</TableCell>
<TableCell>{formData.comment}</TableCell>
</TableRow>
</TableBody>
</Table>
</Box>
</>
)
})
export default StepSummary
enum SubmitState {
NotSubmitted,
SubmitSuccess,
SubmitFailure
SubmitFailure,
}
export default SubmitState
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment