From abf2fe55dcdadb367de4a889bc6b02eb40743b99 Mon Sep 17 00:00:00 2001 From: Dave Trost Date: Mon, 21 Dec 2020 11:30:30 -0800 Subject: [PATCH 1/3] add tenant validation to match backend requirements Special handling for blank values in: unit number, occupants. Backend validation requires `null` instead of empty string Custom form validation: property ID is required ONLY when lease dates are supplied - use Formik's "validate" hook to drive new state for the error messages on propertyID The form resets all fields after submission - `preSelectedChoices` was the trick to get previously selected "chips" to disappear from SearchPanel components indentation fixes --- src/views/AddTenant/addTenant.js | 73 ++++++++++++++++++++++---------- 1 file changed, 50 insertions(+), 23 deletions(-) diff --git a/src/views/AddTenant/addTenant.js b/src/views/AddTenant/addTenant.js index ccd9ddd7c..dfd7c8913 100644 --- a/src/views/AddTenant/addTenant.js +++ b/src/views/AddTenant/addTenant.js @@ -23,7 +23,7 @@ const validationSchema = Yup.object().shape({ .min(7, "*Phone Number must have at least 7 characters") .max(20, "*Phone Number can't be longer than 20 characters") .required("*Phone Number is required"), - unitNum: Yup.number(), + unitNum: Yup.string(), occupants: Yup.number(), }); @@ -39,12 +39,16 @@ export const AddTenant = () => { const [propertyOptions, setPropertyOptions] = useState([]); const [propertySearchResults, setPropertySearchResults] = useState([]); const [showAddProperty, setShowAddProperty] = useState(false); + const [isValidationActive, setIsValidationActive] = useState(false); + const [propertyErrorText, setPropertyErrorText] = useState(""); const calendarState = useCalendarState(); - const { dateTimeStart, dateTimeEnd, } = calendarState; + const { dateTimeStart, dateTimeEnd } = calendarState; useMountEffect(() => getProperties()); + useEffect(() => validateForm(), [propertySelection, dateTimeStart, dateTimeEnd]); + useEffect(() => { axios.post("/api/users/role", { userrole: RoleEnum.STAFF, @@ -88,13 +92,8 @@ export const AddTenant = () => { }; const handleFormSubmit = (data) => { - let body = { - ...data, - propertyID: propertySelection[0].key, - staffIDs: staffSelections && staffSelections.map(staff => staff.key) - }; axios - .post(`/api/tenants`, body, makeAuthHeaders(context)) + .post(`/api/tenants`, data, makeAuthHeaders(context)) .then((response) => { Toast("Tenant Created Successfully!", "success"); }) @@ -144,6 +143,17 @@ export const AddTenant = () => { setStaffSelections(selectedChoices); }; + const validateForm = (values) => { + setIsValidationActive(true); + + if (dateTimeStart !== dateTimeEnd) { + setPropertyErrorText(dateTimeStart !== dateTimeEnd && propertySelection && propertySelection.length + ? "" + : "*Property is a required field" + ); + } + }; + return (
@@ -158,16 +168,30 @@ export const AddTenant = () => { occupants: "", }} validationSchema={validationSchema} + validate={validateForm} validateOnBlur={false} - onSubmit={(values, { setSubmitting }) => { + onSubmit={(values, { setSubmitting, resetForm }) => { const toSubmit = { ...values, - dateTimeStart, - dateTimeEnd, + occupants: values.occupants || null, + unitNum: values.unitNum || null, + propertyID: propertySelection[0].key, + staffIDs: staffSelections && staffSelections.map(staff => staff.key) }; + if (dateTimeStart !== dateTimeEnd) { + toSubmit.dateTimeStart = dateTimeStart; + toSubmit.dateTimeEnd = dateTimeEnd; + } setSubmitting(true); handleFormSubmit(toSubmit); + resetForm(); + setPropertySearchText(""); + setPropertySelection([]); + setStaffSearchText(""); + setStaffSelections([]); + setPropertyErrorText(""); + setIsValidationActive(false); setSubmitting(false); }} > @@ -275,16 +299,20 @@ export const AddTenant = () => { onSelectionChange={setPropertySelection} onChange={handlePropertySearch} onClear={handlePropertySearch} + preSelectedChoices={propertySelection} shadow /> + {isValidationActive && propertyErrorText ? ( +
{propertyErrorText}
+ ) : null} + Create New Property +

UNIT

@@ -294,17 +322,17 @@ export const AddTenant = () => { htmlFor="number" > Number - + - {errors.number ? ( -
{errors.number}
+ {errors.unitNum ? ( +
{errors.unitNum}
) : null}
@@ -339,15 +367,14 @@ export const AddTenant = () => { className="column form-field" type="text" name="lease" - onChange={null} - value={dateTimeEnd !== dateTimeStart ? `${dateTimeStart.toDateString()} - ${dateTimeEnd.toDateString()}` : ""} - + onChange={validateForm} + value={dateTimeEnd !== dateTimeStart + ? `${dateTimeStart.toDateString()} - ${dateTimeEnd.toDateString()}` + : "" + } placeholder="Lease dates (Start and End)" /> - {errors.lease ? ( -
{errors.lease}
- ) : null}
-

UNIT

+

LEASE

From 74c78083befe7e964554c5a05855771b532c6ea8 Mon Sep 17 00:00:00 2001 From: Dave Trost Date: Tue, 22 Dec 2020 21:16:24 -0800 Subject: [PATCH 3/3] bugfix to allow an empty field for propertyID --- src/views/AddTenant/addTenant.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/views/AddTenant/addTenant.js b/src/views/AddTenant/addTenant.js index 4767cea8a..03666d4e1 100644 --- a/src/views/AddTenant/addTenant.js +++ b/src/views/AddTenant/addTenant.js @@ -147,7 +147,7 @@ export const AddTenant = () => { setIsValidationActive(true); if (dateTimeStart !== dateTimeEnd) { - setPropertyErrorText(dateTimeStart !== dateTimeEnd && propertySelection && propertySelection.length + setPropertyErrorText(dateTimeStart !== dateTimeEnd && propertySelection.length ? "" : "*Property is a required field" ); @@ -175,7 +175,7 @@ export const AddTenant = () => { ...values, occupants: values.occupants || null, unitNum: values.unitNum || null, - propertyID: propertySelection[0].key, + propertyID: propertySelection.length ? propertySelection[0].key : null, staffIDs: staffSelections && staffSelections.map(staff => staff.key) }; if (dateTimeStart !== dateTimeEnd) {