import React, { useEffect, useState, useMemo, useContext } from 'react'; import styled from 'styled-components/macro'; import * as yup from 'yup'; import { yupResolver } from '@hookform/resolvers/yup'; import { useForm, Controller, SubmitHandler } from 'react-hook-form'; import DatePicker from 'react-datepicker'; import 'react-datepicker/dist/react-datepicker.css'; import { useDispatch, useSelector } from 'react-redux'; import { useHistory } from 'react-router-dom'; import FormInput from 'components/FormInput'; import CustomCheckbox from 'components/CustomCheckbox'; import { getUser } from 'redux/reducers/user'; import CustomModalContext from 'contexts/CustomModalContext'; import { useActions } from 'hooks/useActions'; import LearningPackageBody from 'pages/Signup/SelectLearningPackages/LearningPackageBody'; import instance from 'api/axiosInstance'; import { getFormattedSuggestYear } from 'utils/url'; import { formatDateForRegistration } from 'utils/Date'; export interface IStudentAccountForm { firstName: string; lastName: string; userName: string; password: string; dateOfBirth?: Date; email: string; isStudentFourYear?: boolean; grateStudent?: string; } type Props = { isModal?: boolean; }; const grateStudentArr = [ { value: '3', title: 'Year 3', }, { value: '4', title: 'Year 4', }, { value: '5', title: 'Year 5', }, { value: '6', title: 'Year 6', }, ]; const schema = yup.object({ firstName: yup.string().required('First Name is a required field'), lastName: yup.string().required('Last Name is a required field'), userName: yup.string().required('User Name is a required field'), password: yup.string().required('Password is a required field'), dateOfBirth: yup.string().nullable().required('Date of Birth is a required field'), email: yup.string().email(), isStudentFourYear: yup.boolean(), grateStudent: yup.string(), }); const CreateStudentModal: React.FC<Props> = ({ isModal }) => { const { setStudentAccount } = useActions(); const customModalContext = useContext(CustomModalContext); const { hideModal, setActiveView } = customModalContext; const history = useHistory(); const dispatch = useDispatch(); const currentUser = useSelector(getUser); const studentWhenAppClosed = JSON.parse(localStorage.getItem('studentAccount') || '{}'); const memoizedIsCurUserIdEqualsStudentId = useMemo( () => currentUser.userId === studentWhenAppClosed?.parentId, // eslint-disable-next-line react-hooks/exhaustive-deps [currentUser, studentWhenAppClosed], ); const [studentYear, setStudentYear] = useState(''); const { register, formState: { errors }, control, handleSubmit, watch, setValue, } = useForm<IStudentAccountForm>({ defaultValues: { firstName: Boolean(studentWhenAppClosed?.firstName) ? studentWhenAppClosed.firstName : '', lastName: Boolean(studentWhenAppClosed?.lastName) ? studentWhenAppClosed.lastName : '', userName: Boolean(studentWhenAppClosed?.userName) ? studentWhenAppClosed.userName : '', password: Boolean(studentWhenAppClosed?.password) ? studentWhenAppClosed.password : '', email: Boolean(studentWhenAppClosed?.email) ? studentWhenAppClosed.email : '', isStudentFourYear: studentWhenAppClosed?.isStudentFourYear ? studentWhenAppClosed.isStudentFourYear : true, grateStudent: Boolean(studentWhenAppClosed?.grateStudent) ? studentWhenAppClosed.grateStudent : '', }, resolver: yupResolver(schema), }); const newDate = watch('dateOfBirth'); const isStudentFourYear = watch('isStudentFourYear'); const grateStudentValue = watch('grateStudent'); const onSubmit: SubmitHandler<IStudentAccountForm> = async (data) => { dispatch( setStudentAccount({ firstName: data.firstName, lastName: data.lastName, userName: data.userName, password: data.password, dateOfBirth: data.dateOfBirth!, email: data.email, isStudentFourYear: data.isStudentFourYear, grateStudent: data.grateStudent, }), ); !isModal && history.push('/select-learning-packages'); localStorage.setItem( 'studentAccount', JSON.stringify({ ...data, dateOfBirth: data.dateOfBirth!, parentId: currentUser.userId }), ); }; const createStudentAccount: SubmitHandler<IStudentAccountForm> = async (data) => { setActiveView({ component: LearningPackageBody, props: { student: data, isModal, }, }); }; const getDate = async () => { try { const selectedDate = newDate; const formattedDateValue = formatDateForRegistration(selectedDate); const payload = { date: formattedDateValue, }; if (formattedDateValue === 'Invalid Date') { return; } const response = await instance.post(getFormattedSuggestYear, payload); if (response !== null) { setStudentYear(response.data.year); if (!isStudentFourYear) { setValue('isStudentFourYear', false); } else if (String(response.data.year) === grateStudentValue) { setValue('isStudentFourYear', true); } else { setValue('grateStudent', String(response.data.year)); } } return response; } catch (e) { console.log(e); } }; useEffect(() => { getDate(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [grateStudentValue, newDate, isStudentFourYear]); useMemo(() => { if (!memoizedIsCurUserIdEqualsStudentId) { localStorage.removeItem('studentAccount'); } }, [memoizedIsCurUserIdEqualsStudentId]); return ( <StyledContainer isModal={isModal}> {!isModal ? <h3 className="create-student-account__title">Create Student Account</h3> : null} <form className="create-student-account__form" onSubmit={isModal ? handleSubmit(createStudentAccount) : handleSubmit(onSubmit)} > <div className="create-student-account__form-fields-wrapper"> <StyledFormInput label="First Name" name="firstName" error={errors.firstName} register={register} placeholder="Enter a first name" inputType="text" /> <StyledFormInput label="Last Name" name="lastName" error={errors.lastName} register={register} placeholder="Enter a last name" inputType="text" /> <StyledFormInput label="User Name" name="userName" error={errors.userName} register={register} placeholder="Enter a user name" inputType="text" /> <StyledFormInput label="Password" name="password" error={errors.password} register={register} placeholder="Enter a password" inputType="password" /> <Controller name="dateOfBirth" control={control} defaultValue={ Boolean(studentWhenAppClosed?.dateOfBirth) ? (new Date(studentWhenAppClosed?.dateOfBirth) as unknown as Date) : (new Date() as unknown as Date) } render={({ field: { onChange, value } }) => ( <div className="create-student-account__date-wrapper"> <label htmlFor="date" className="create-student-account__label"> Date of Birth </label> <StyledDatePicker id="date" onChange={onChange} selected={value} value={value as unknown as string} placeholderText="Enter a date of birthday" onKeyDown={(e) => { e.preventDefault(); }} dateFormat="MM/dd/yyyy" dateFormatCalendar="MM/dd/yyyy" /> <p className="create-student-account__error">{errors?.dateOfBirth?.message}</p> </div> )} /> <StyledFormInput label="Email Address (optional):" name="email" error={errors.email} register={register} placeholder="Enter a email" inputType="text" /> <div className="create-student-account__checkbox-form-wrapper"> <p className="create-student-account__checkbox-title">Is this student in year {studentYear}?</p> <Controller render={({ field: { onChange, value } }) => ( <StyledCustomCheckbox title="Yes" name="Yes" register={register} onChange={() => onChange(true)} checked={value} /> )} name="isStudentFourYear" control={control} /> <Controller render={({ field: { onChange, value } }) => ( <StyledCustomCheckbox title="No" name="No" register={register} onChange={() => onChange(false)} checked={!value} /> )} name="isStudentFourYear" control={control} /> </div> <div className="create-student-account__checkbox-form-wrapper"> <p className="create-student-account__checkbox-title">What grate is the student? </p> {grateStudentArr.map((item, index) => ( <Controller key={index} render={({ field: { onChange, value } }) => ( <StyledCustomCheckbox title={item.title} register={register} name={item.title} onChange={() => onChange(item.value)} disabled={isStudentFourYear} checked={value === item.value} /> )} name="grateStudent" control={control} /> ))} </div> </div> {!isModal ? ( <button className="create-student-account__form-button-next" type="submit"> Next </button> ) : ( <div className="create-student-account__buttons-wrapper"> <button className="create-student-account__close-button" type="button" onClick={hideModal}> Close </button> <button className="create-student-account__form-button-next" type="submit"> Add Student </button> </div> )} </form> </StyledContainer> ); }; const StyledContainer = styled.div<Props>` width: ${(props) => (props.isModal ? '901px' : '1016px')}; margin: 0 auto; background: white; border-radius: ${(props) => (props.isModal ? 0 : '25px')}; padding: ${(props) => (props.isModal ? 0 : '42px 68px 58px')}; border-top: ${(props) => (props.isModal ? '1px solid #ececec' : 'none')}; padding-top: ${(props) => (props.isModal ? '32px' : 'none')}; font-family: ${({ theme }) => theme.font.fontFamily.popins}; .create-student-account { &__title { font-size: 30px; line-height: 39px; letter-spacing: 0.43px; color: #20114d; margin: 0; padding-bottom: 25px; font-weight: 600; border-bottom: 1px solid #ececec; margin-bottom: 18px; } &__form { display: flex; flex-direction: column; align-items: center; justify-content: start; } &__form-fields-wrapper { width: 100%; display: grid; grid-template-columns: repeat(2, 1fr); grid-template-rows: repeat(3, max-content); column-gap: 28px; row-gap: 10px; margin-bottom: 51px; } &__checkbox-form-wrapper { display: grid; grid-template-columns: min-content repeat(2, 0.1fr); column-gap: 45px; grid-column: 1 / 3; :last-of-type { grid-template-columns: min-content repeat(4, 0.1fr); } } &__checkbox-title { font-family: ${({ theme }) => theme.font.fontFamily.popins}; font-weight: 600; font-size: 16px; line-height: 18px; letter-spacing: 0.2px; width: 221px; color: #20114d; } &__form-button-next { padding: 11px 30px; width: fit-content; color: white; background: #32e790; text-align: center; font-weight: 600; font-size: 14px; line-height: 18px; letter-spacing: 0.2px; border-radius: 27px; border: 2px solid #32e790; align-self: end; cursor: pointer; font-family: ${({ theme }) => theme.font.fontFamily.popins}; :last-of-type { padding: 9px 34px; } } &__date-wrapper { display: flex; flex-direction: column; justify-content: start; } &__label { margin: 0 0 10px 0; margin-bottom: 10px; font-size: 14px; color: #20114d; font-weight: 400; } &__error { font-size: 9px; color: red; margin-top: 5px; text-transform: capitalize; } &__buttons-wrapper { display: flex; flex-direction: row; align-items: space-between; justify-content: space-between; width: 100%; } &__close-button { padding: 9px 34px; width: 157px; color: rgba(245, 80, 83, 1); background: white; text-align: center; font-weight: 600; font-size: 14px; line-height: 18px; letter-spacing: 0.2px; border-radius: 27px; border: 2px solid rgba(245, 80, 83, 1); align-self: end; cursor: pointer; } } `; const StyledCustomCheckbox = styled(CustomCheckbox)` width: 90px; label { font-family: ${({ theme }) => theme.font.fontFamily.popins}; font-weight: ${({ theme }) => theme.font.fontWeight.medium}; font-size: 16px; line-height: 18px; letter-spacing: 0.2px; color: #20114d; } .custom-checkbox + label { position: relative; } .custom-checkbox + label::before { width: 23px; height: 23px; border-radius: 50%; width: 1.5em; height: 1.5em; } .custom-checkbox:checked + label::before { background-color: #41e85b; background-image: none; } .custom-checkbox:checked + label::after { content: ''; width: 14px; height: 14px; position: absolute; border-radius: 50%; left: 5px; background-color: #41e85b; border: 2px solid white; } `; const StyledDatePicker = styled(DatePicker)` border: 1px solid #dad1c9; border-radius: 13px; padding: 11px 15px 11px 15px; outline: none; width: 100%; font-weight: 600; font-size: 16px; line-height: 18px; letter-spacing: 0.2px; font-family: ${({ theme }) => theme.font.fontFamily.popins}; ::placeholder { color: rgba(32, 17, 77, 0.5); font-family: ${({ theme }) => theme.font.fontFamily.popins}; } `; const StyledFormInput = styled(FormInput)` font-weight: 600; font-size: 16px; line-height: 18px; letter-spacing: 0.2px; color: rgb(166, 160, 184); font-family: ${({ theme }) => theme.font.fontFamily.popins}; ::after { color: #20114d; } `; export default CreateStudentModal;