Unverified Commit 736a3a04 authored by Zhou (Link)  Fang's avatar Zhou (Link) Fang Committed by GitHub
Browse files

Multiple improvements (#164)

* Added twitter handle validation

* improved validation and sameAs checkbox logic

* Made the page scroll to top when it shows up

* updated the twitter handle validation

* fixed can't go to next step issue in React Only mode
parent 5e78fd9b
...@@ -515,6 +515,9 @@ function callSendData( ...@@ -515,6 +515,9 @@ function callSendData(
if (getCurrentMode() === MODE_REACT_ONLY) { if (getCurrentMode() === MODE_REACT_ONLY) {
console.log(`You called ${url} with Method ${method} and data body is:`); console.log(`You called ${url} with Method ${method} and data body is:`);
console.log(JSON.stringify(dataBody)); console.log(JSON.stringify(dataBody));
if (goToNextStepObj) {
goToNextStepObj.method(goToNextStepObj.stepNum, goToNextStepObj.pathName);
}
} }
if (getCurrentMode() === MODE_REACT_API) { if (getCurrentMode() === MODE_REACT_API) {
...@@ -708,3 +711,7 @@ export function requestErrorHandler( ...@@ -708,3 +711,7 @@ export function requestErrorHandler(
break; break;
} }
} }
export function scrollToTop() {
window.scrollTo({ top: 0, behavior: 'smooth' });
}
...@@ -6,6 +6,7 @@ import { ...@@ -6,6 +6,7 @@ import {
matchCompanyFields, matchCompanyFields,
matchContactFields, matchContactFields,
requestErrorHandler, requestErrorHandler,
scrollToTop,
} from '../../../Utils/formFunctionHelpers'; } from '../../../Utils/formFunctionHelpers';
import CompanyInformationCompany from './CompanyInformationCompany'; import CompanyInformationCompany from './CompanyInformationCompany';
import CompanyInformationContacts from './CompanyInformationContacts'; import CompanyInformationContacts from './CompanyInformationContacts';
...@@ -57,6 +58,10 @@ const CompanyInformation = ({ ...@@ -57,6 +58,10 @@ const CompanyInformation = ({
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const { setFieldValue } = formik; const { setFieldValue } = formik;
useEffect(() => {
scrollToTop();
}, []);
useEffect(() => { useEffect(() => {
const detectModeAndFetch = () => { const detectModeAndFetch = () => {
// Once we have API set up ready, we don't need the // Once we have API set up ready, we don't need the
......
...@@ -47,6 +47,8 @@ const CompanyInformationCompany = ({ formik, useStyles }) => { ...@@ -47,6 +47,8 @@ const CompanyInformationCompany = ({ formik, useStyles }) => {
requiredMark={true} requiredMark={true}
value={formik.values.organization.twitterHandle} value={formik.values.organization.twitterHandle}
onChange={formik.handleChange} onChange={formik.handleChange}
error={Boolean(formik.errors.organization?.twitterHandle)}
helperText={formik.errors.organization?.twitterHandle}
/> />
</div> </div>
</div> </div>
......
...@@ -49,31 +49,44 @@ const Contacts = ({ formik }) => { ...@@ -49,31 +49,44 @@ const Contacts = ({ formik }) => {
}; };
const handleMemberInputChange = (value, name) => { const handleMemberInputChange = (value, name) => {
const representativeValue = formik.values.representative;
const memberRepInfo = { const memberRepInfo = {
...formik.values.representative.member, ...representativeValue.member,
[name]: value, [name]: value,
}; };
formik.setFieldValue('representative.member', memberRepInfo);
let newRepresentativeValue = {
...representativeValue,
member: memberRepInfo,
};
// update representative.marketing values based on related checkbox // update representative.marketing values based on related checkbox
if (isMarketingSameAsCompany) { if (isMarketingSameAsCompany) {
const newValues = { const newMarketingRepValues = {
...memberRepInfo, ...memberRepInfo,
id: formik.values.representative.marketing.id || '', id: representativeValue.marketing.id || '',
sameAsCompany: isMarketingSameAsCompany, sameAsCompany: isMarketingSameAsCompany,
}; };
formik.setFieldValue('representative.marketing', newValues); newRepresentativeValue = {
...newRepresentativeValue,
marketing: newMarketingRepValues,
};
} }
// update representative.accounting values based on related checkbox // update representative.accounting values based on related checkbox
if (isAccountingSameAsCompany) { if (isAccountingSameAsCompany) {
const newValues = { const newAccountingRepValues = {
...memberRepInfo, ...memberRepInfo,
id: formik.values.representative.accounting.id || '', id: representativeValue.accounting.id || '',
sameAsCompany: isAccountingSameAsCompany, sameAsCompany: isAccountingSameAsCompany,
}; };
formik.setFieldValue('representative.accounting', newValues); newRepresentativeValue = {
...newRepresentativeValue,
accounting: newAccountingRepValues,
};
} }
formik.setFieldValue('representative', newRepresentativeValue);
}; };
const generateContacts = ( const generateContacts = (
...@@ -98,14 +111,8 @@ const Contacts = ({ formik }) => { ...@@ -98,14 +111,8 @@ const Contacts = ({ formik }) => {
: formik.handleChange : formik.handleChange
} }
value={formik.values.representative?.[type]?.[el.name]} value={formik.values.representative?.[type]?.[el.name]}
error={ error={Boolean(formik.errors.representative?.[type]?.[el.name])}
formik.touched.representative?.[type]?.[el.name] && helperText={formik.errors.representative?.[type]?.[el.name]}
Boolean(formik.errors.representative?.[type]?.[el.name])
}
helperText={
formik.touched.representative?.[type]?.[el.name] &&
formik.errors.representative?.[type]?.[el.name]
}
/> />
</div> </div>
))} ))}
......
...@@ -4,6 +4,8 @@ import Autocomplete from '@material-ui/lab/Autocomplete'; ...@@ -4,6 +4,8 @@ import Autocomplete from '@material-ui/lab/Autocomplete';
import CustomStepButton from '../../UIComponents/Button/CustomStepButton'; import CustomStepButton from '../../UIComponents/Button/CustomStepButton';
import { formField } from '../../UIComponents/FormComponents/formFieldModel'; import { formField } from '../../UIComponents/FormComponents/formFieldModel';
import { MEMBERSHIP_LEVELS } from '../../../Constants/Constants'; import { MEMBERSHIP_LEVELS } from '../../../Constants/Constants';
import { useEffect } from 'react';
import { scrollToTop } from '../../../Utils/formFunctionHelpers';
/** /**
* Render membership select component (use React-Select), with fetch and prefill data operation * Render membership select component (use React-Select), with fetch and prefill data operation
...@@ -25,6 +27,10 @@ const MembershipLevel = ({ formik }) => { ...@@ -25,6 +27,10 @@ const MembershipLevel = ({ formik }) => {
const { membershipLevel } = formField; const { membershipLevel } = formField;
const classes = useStyles(); const classes = useStyles();
useEffect(() => {
scrollToTop();
}, []);
return ( return (
<form onSubmit={formik.handleSubmit}> <form onSubmit={formik.handleSubmit}>
<div className="align-center"> <div className="align-center">
......
import React from 'react'; import React, { useEffect } from 'react';
import CustomStepButton from '../../UIComponents/Button/CustomStepButton'; import CustomStepButton from '../../UIComponents/Button/CustomStepButton';
import { FormValue } from '../../../Interfaces/form_interface'; import { FormValue } from '../../../Interfaces/form_interface';
import { scrollToTop } from '../../../Utils/formFunctionHelpers';
interface ReviewProps { interface ReviewProps {
values: FormValue; values: FormValue;
...@@ -8,6 +9,10 @@ interface ReviewProps { ...@@ -8,6 +9,10 @@ interface ReviewProps {
} }
const Review: React.FC<ReviewProps> = ({ values, submitForm }) => { const Review: React.FC<ReviewProps> = ({ values, submitForm }) => {
useEffect(() => {
scrollToTop();
}, []);
return ( return (
<form onSubmit={() => submitForm(5, '/submitted')}> <form onSubmit={() => submitForm(5, '/submitted')}>
<h1 className="fw-600 h2"> <h1 className="fw-600 h2">
......
import CustomStepButton from '../../UIComponents/Button/CustomStepButton'; import CustomStepButton from '../../UIComponents/Button/CustomStepButton';
import Input from '../../UIComponents/Inputs/Input'; import Input from '../../UIComponents/Inputs/Input';
import { formField } from '../../UIComponents/FormComponents/formFieldModel'; import { formField } from '../../UIComponents/FormComponents/formFieldModel';
import { useEffect } from 'react';
import { scrollToTop } from '../../../Utils/formFunctionHelpers';
/** /**
* Have not added any API calls here, * Have not added any API calls here,
...@@ -12,6 +14,10 @@ const sectionName = 'signing-authority'; ...@@ -12,6 +14,10 @@ const sectionName = 'signing-authority';
const SigningAuthority = ({ formik }) => { const SigningAuthority = ({ formik }) => {
const { signingAuthorityRepresentative } = formField; const { signingAuthorityRepresentative } = formField;
useEffect(() => {
scrollToTop();
}, []);
return ( return (
<form onSubmit={formik.handleSubmit}> <form onSubmit={formik.handleSubmit}>
<h1 className="fw-600 h2" id={sectionName}> <h1 className="fw-600 h2" id={sectionName}>
......
import { useEffect } from 'react';
import { scrollToTop } from '../../../Utils/formFunctionHelpers';
/** /**
* This is just a pure html component to * This is just a pure html component to
* display after all steps finished and * display after all steps finished and
* final submitted after preview * final submitted after preview
*/ */
const SubmitSuccess = () => { const SubmitSuccess = () => {
useEffect(() => {
scrollToTop();
}, []);
return ( return (
<> <>
<h2>Confirmation message on submission: </h2> <h2>Confirmation message on submission: </h2>
......
...@@ -4,6 +4,7 @@ import WorkingGroup from './WorkingGroup'; ...@@ -4,6 +4,7 @@ import WorkingGroup from './WorkingGroup';
import { import {
matchWorkingGroupFields, matchWorkingGroupFields,
requestErrorHandler, requestErrorHandler,
scrollToTop,
} from '../../../Utils/formFunctionHelpers'; } from '../../../Utils/formFunctionHelpers';
import Loading from '../../UIComponents/Loading/Loading'; import Loading from '../../UIComponents/Loading/Loading';
import { import {
...@@ -49,6 +50,10 @@ const WorkingGroupsWrapper = ({ ...@@ -49,6 +50,10 @@ const WorkingGroupsWrapper = ({
const [workingGroupsUserJoined, setWorkingGroupsUserJoined] = useState([]); const [workingGroupsUserJoined, setWorkingGroupsUserJoined] = useState([]);
const [fullWorkingGroupList, setFullWorkingGroupList] = useState([]); const [fullWorkingGroupList, setFullWorkingGroupList] = useState([]);
useEffect(() => {
scrollToTop();
}, []);
// Fetch data only once and prefill data, as long as // Fetch data only once and prefill data, as long as
// fetchWorkingGroupsData Function does not change, // fetchWorkingGroupsData Function does not change,
// will not cause re-render again // will not cause re-render again
......
...@@ -34,15 +34,22 @@ export const validationSchema = [ ...@@ -34,15 +34,22 @@ export const validationSchema = [
// First step - company Info // First step - company Info
yup.object().shape({ yup.object().shape({
// First step - representative contacts // First step - representative contacts
organization: yup.object().shape({
twitterHandle: yup
.string()
.min(2, 'Twitter handle is too short')
.max(16, 'Twitter handle is too long')
.matches(/^@([A-Za-z0-9_])*$/, 'Please enter a valid Twitter handle'),
}),
representative: yup.object().shape({ representative: yup.object().shape({
member: yup.object().shape({ member: yup.object().shape({
email: yup.string('Enter your email').email('Enter a valid email'), email: yup.string().email('Please enter a valid email'),
}), }),
marketing: yup.object().shape({ marketing: yup.object().shape({
email: yup.string('Enter your email').email('Enter a valid email'), email: yup.string().email('Please enter a valid email'),
}), }),
accounting: yup.object().shape({ accounting: yup.object().shape({
email: yup.string('Enter your email').email('Enter a valid email'), email: yup.string().email('Please enter a valid email'),
}), }),
}), }),
}), }),
...@@ -57,7 +64,7 @@ export const validationSchema = [ ...@@ -57,7 +64,7 @@ export const validationSchema = [
workingGroups: yup.array().of( workingGroups: yup.array().of(
yup.object().shape({ yup.object().shape({
workingGroupRepresentative: yup.object().shape({ workingGroupRepresentative: yup.object().shape({
email: yup.string('Enter your email').email('Enter a valid email'), email: yup.string().email('Please enter a valid email'),
}), }),
}) })
), ),
...@@ -69,7 +76,7 @@ export const validationSchema = [ ...@@ -69,7 +76,7 @@ export const validationSchema = [
firstName: yup.string().required(`${requiredErrorMsg}`), firstName: yup.string().required(`${requiredErrorMsg}`),
lastName: yup.string().required(`${requiredErrorMsg}`), lastName: yup.string().required(`${requiredErrorMsg}`),
jobtitle: yup.string().required(`${requiredErrorMsg}`), jobtitle: yup.string().required(`${requiredErrorMsg}`),
email: yup.string('Enter your email').email('Enter a valid email'), email: yup.string().email('Please enter a valid email'),
}), }),
}), }),
]; ];
...@@ -20,6 +20,8 @@ const useStyles = makeStyles(() => ({ ...@@ -20,6 +20,8 @@ const useStyles = makeStyles(() => ({
root: { root: {
marginBottom: 14, marginBottom: 14,
marginTop: 6, marginTop: 6,
},
input: {
backgroundColor: 'white', backgroundColor: 'white',
}, },
})); }));
...@@ -55,6 +57,7 @@ export default function Input(props) { ...@@ -55,6 +57,7 @@ export default function Input(props) {
fullWidth={true} fullWidth={true}
placeholder={placeholder} placeholder={placeholder}
InputProps={{ InputProps={{
className: classes.input,
inputProps: { inputProps: {
'aria-labelledby': ariaLabel, 'aria-labelledby': ariaLabel,
}, },
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment