This is the upload version 2 using MDB version 5. In small screen version, the columns will become only one column. MBD uses bootstrap : https://mdbootstrap.com/docs/react/layout/grid/

Source: /f/apachefriends/xampp/htdocs/over-imgV5/REACT/Version2/OPENSOURCE/MDB/mdb5/src/pages/start/upload/Upload.jsx

import { MDBBtn, MDBCol, MDBInput, MDBRow, MDBSpinner, MDBTextArea, MDBValidation, MDBValidationItem } from "mdb-react-ui-kit";

 Define the Object Array

    const [formValue, setFormValue] = useState([
        { divider: "Your Information" },
        // name row
        {
            files_fname: {
                value: 'Edward',
                errorMsg: 'Please enter your first name.',
                type: 'text',
                label: 'First Name',
                divider: "Your Information" // ADD A DIVIVER BEFORE THIS FIELD
            },
            files_lname: {
                value: 'Smith',
                errorMsg: 'Please enter your last name.',
                type: 'text',
                label: 'Last Name',
            }
        },
        // Contact row
        {
            files_phone: {
                value: '2135551212',
                errorMsg: 'Please enter your phone number.',
                type: 'text',
                label: 'Phone Number',
            },

            files_email: {
                value: '[email protected]',
                errorMsg: 'Please enter a valid email',
                type: 'email',
                label: 'Your email',
            }
        }
        , {
            // DETAILS GROUP
            files_title: {
                value: 'Homework Files',
                errorMsg: 'Please enter brief description of your files',
                type: 'text',
                label: 'Documents Title',
            },
            files_description: {
                value: 'These are the pictures you can use for your pumkin project.',
                errorMsg: 'Please enter a Description of what the files are about.',
                type: 'textarea',
                label: 'Documents Description'
            }
        },
        { divider: "Recipient's Information" },
        {
            recipient_fname: {
                value: 'Sandy',
                errorMsg: 'Please enter the recipients\'s first name.',
                type: 'text',
                label: 'First Name',
                divider: "Recipient's Information" // ADD A DIVIVER BEFORE THIS FIELD
            },
            recipient_lname: {
                value: 'Johnson',
                errorMsg: 'Please enter the recipients\'s last name.',
                type: 'text',
                label: 'Last Name',
            }
        },
        {
            recipient_phone: {
                value: '4155551212',
                errorMsg: 'Please enter the recipients\'s phone number.',
                type: 'text',
                label: 'Phone Number',
            },
            recipient_email: {
                value: '[email protected]',
                errorMsg: 'Please enter a valid recipients\'semail for the ',
                type: 'email',
                label: 'Your email',
            }
        },
    ]);

 

JSX Usage:

            <MDBValidation className='row g-3 ' id='myform' onSubmit={e => submitRecipientInformation(e)}>
                {formValue.map((group, index) => {
                    return (
                        <div key={index}>
                            {
                                typeof group.divider != "undefined" ?
                                    <h4 className="my-3  text-center" style={{ borderBottom: '1px solid #000', lineHeight: '0.1em', margin: '10px 0 20x' }}><span style={{ background: "#FFF", padding: "0 10px" }}>{group.divider}</span></h4>
                                    :
                                    <MDBRow className="mt-3" >
                                        {Object.entries(group).map(([fieldname, field], index2) => {
                                            return (
                                                <MDBCol key={index2} size={`md-${ 12/Object.entries(group).length }`}>
                                                    <MDBValidationItem feedback={field.errorMsg} invalid className='col-md-12' >
                                                        {field.type == 'textarea' ?
                                                            <MDBTextArea
                                                                value={field.value}
                                                                name={fieldname}
                                                                onChange={updateFieldValue}
                                                                required
                                                                label={field.label}
                                                                id={fieldname}
                                                                type={field.type}
                                                                rows={2}
                                                                dataIndex={index}
                                                                className={`${Object.entries(group).length>1 && 'mb-3'}`}
                                                                />
                                                            :
                                                            <MDBInput
                                                                value={field.value}
                                                                name={fieldname}
                                                                onChange={updateFieldValue}
                                                                required
                                                                label={field.label}
                                                                id={fieldname}
                                                                type={field.type}
                                                                dataIndex={index}
                                                                className={`${Object.entries(group).length>1 && 'mb-3'}`}
                                                            />
                                                        }
                                                    </MDBValidationItem>
                                                </MDBCol>
                                            )
                                        })}
                                    </MDBRow>
                            }
                        </div>
                    )
                })}
                <MDBBtn color="success mt-4" type='submit' block >Continue</MDBBtn>
            </MDBValidation>

 

Update Field Value State:

    const updateFieldValue = (e) => {
        //https://stackoverflow.com/questions/20377837/how-to-access-custom-attributes-from-event-object-in-react
        //console.log(`LINE 306 e=`, e.target.getAttribute('dataindex'));//dataIndex=1
        let dataIndex = e.target.getAttribute('dataindex');
        let fieldName = e.target.name;
        let fieldValue = e.target.value;
        // check if field is defined in formValue
        let formValueTemp = [...formValue]
        if (typeof formValueTemp[dataIndex][fieldName] == "undefined") {
            // dont do anything if this field does not exist in the object
            return false;;
        }
        formValueTemp[dataIndex][fieldName].value = fieldValue;
        setFormValue(formValueTemp);
    };

On Submit

    const submitRecipientInformation = (ev) => {
        ev.preventDefault();
        //return false;
        // alert('submitted');
        // setFormSubmitted(true); return false;
        const postData = {
            //fileSecret: fileSecret, //xyz123 | asof 10/22/23 - the secre_key will be generated in Backedn.
            apiRoute: componentSettings.apiRoute
        };
        //Loop through object to get field names and values to generate the postData Object{}
        for (let [property, field] of Object.entries(formValue)) {
            console.log(`LINE 93 property=`, property);
            let fieldName = Object.keys(field)[0];
            console.log(`LINE 93b field=`, Object.keys(field)[0]);
            if (fieldName == 'divider') continue; // skip if its divider
            else {
                if (typeof field == "object") {
                    for (let [prop, fi] of Object.entries(field)) {
                        postData[prop] = fi.value;
                    }
                }
            }
        };
        //console.log(`LINE 40 postData=`, postData); return;
        UploadService.UploadForm1(postData)
            .then((response) => {
                console.log(`LINE 125 response.data=`, response.data);
                /*
                        LEFT OF HERE, NEXT I NEED TO CHECK THE response TOKEN AND COMPARE IT TO THE CURRENT TOKEN TO MATCH, IF SO,
                        TAKES USER TO THE LAST PAGE WHERE THE secret_key IS SHOW TO GIVE TO THE RECIPIENT AND
                        FIND A WAY TO SEND EMAILS,
                        TODO:
                        1. ADD A FIELD CALLED RECIPINE FNAME, LNAME AND recipient_email - THIS IS THE PERSON WHO WILL BE RECEIVING THE FILES
                        2. SAVE INCLUDING THE secret_key FROM STEP 1 IN THE DATABASE
                        3. AFTER SUCCESSFUL SEND THIS FORM, TAKE SURE TO 3RD AND FINAL STEP
                        4. ON STEP 3, GIVE THE USER THE secret_key AND INFORMATION ABOUT AN EMAIL WILL BE SENT TO THE RECIPIENT.
                */
                //return false;
                if (typeof response.data.token !== "undefined" && response.data.token.length == 200) {
                    //alert('OK');
 
                    navigate(`${componentSettings.nextRoute}/${response.data.token}`)
                } else {
                    console.log(`LINE 132 Your Details were not saved`);
                    setShowFormError(`response.data.token.length= ${response.data.token.length}`);
                    scrollToFormMsg();
                }
            })
            .catch((error) => {
                console.log(`LINE 108 error=`, error);
            });
    };