dsi-icl/optimise

View on GitHub
packages/optimise-ui/src/components/createPatient/createPatient.jsx

Summary

Maintainability
F
4 days
Test Coverage
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Redirect } from 'react-router-dom';
import moment from 'moment';
import { PickDate } from '../createMedicalElements/datepicker';
import { BackButton } from '../medicalData/utils';
import store from '../../redux/store';
import { createPatientCall } from '../../redux/actions/createPatient';
import style from './createPatient.module.css';

@connect(state => ({
    diagnosesfields: state.availableFields.diagnoses,
    demofields: state.availableFields.demoFields[0],
    patientId: state.createPatient.patientId
}))
class CreatePatient extends Component {    //get these props from state: this.props.visitFields, this.props.patientId
    constructor(props) {
        super(props);
        this.state = {
            dispatched: false,
            aliasId: props.match ? props.match.params.patientIdCreated : '',
            referer: props.match ? props.match.url : undefined,
            givenName: '',
            surname: '',
            address: '',
            postcode: '',
            DOB: moment(),
            showConsentDatePicker: 'N',
            showPregnancyConsentDatePicker: 'N',
            optimiseConsentDate: moment(),
            pregnancyConsentDate: moment(),
            error: false,
            gender: 0,
            dominant_hand: 5,
            ethnicity: 0,
            country_of_origin: 0,
            diagnosis: 0,
            diagnosisDate: moment()
        };
        this._handleDobDateChange = this._handleDobDateChange.bind(this);
        this._handleConsentDateChange = this._handleConsentDateChange.bind(this);
        this._handleDiagnosisDateChange = this._handleDiagnosisDateChange.bind(this);
        this._handleSubmit = this._handleSubmit.bind(this);
        this._handleChange = this._handleChange.bind(this);
        this._handleConsentChange = this._handleConsentChange.bind(this);
        this._handleFreeTextChange = this._handleFreeTextChange.bind(this);
        this._handlePregnancyConsentChange = this._handlePregnancyConsentChange.bind(this);
        this._handlePregnancyConsentDateChange = this._handlePregnancyConsentDateChange.bind(this);
    }

    static getDerivedStateFromProps(nextProps, prevState) {
        let newReferer = nextProps.match ? nextProps.match.url : '';
        let newPatient = nextProps.match ? nextProps.match.params.patientIdCreated : '';
        if (prevState.referer !== newReferer)
            return { ...prevState, referer: newReferer, aliasId: newPatient };
        return prevState;
    }

    _handleDobDateChange(date) {
        this.setState({
            DOB: date,
            error: false
        });
    }

    _handleConsentDateChange(date) {
        this.setState({
            optimiseConsentDate: date,
            error: false
        });
    }

    _handlePregnancyConsentDateChange(date) {
        this.setState({
            optimiseConsentDate: date,
            error: false
        });
    }

    _handleDiagnosisDateChange(date) {
        this.setState({
            diagnosisDate: date,
            error: false
        });
    }

    _handleChange(ev) {
        const newState = { error: false };
        newState[ev.target.name] = parseInt(ev.target.value, 10);
        this.setState(newState);
    }

    _handleConsentChange(ev) {
        const newState = { error: false };
        newState[ev.target.name] = ev.target.value;
        this.setState(newState);
    }

    _handlePregnancyConsentChange(ev) {
        const newState = { error: false };
        newState[ev.target.name] = ev.target.value;
        this.setState(newState);
    }

    _handleFreeTextChange(ev) {
        const newState = { error: false };
        newState[ev.target.name] = ev.target.value;
        this.setState(newState);
    }

    _handleSubmit(ev) {
        ev.preventDefault();
        if (this.state.lastSubmit && (new Date()).getTime() - this.state.lastSubmit < 500 ? true : false)
            return;

        const fieldCheck = ['DOB', 'address', 'aliasId', 'showConsentDatePicker', 'showPregnancyConsentDatePicker', 'country_of_origin', 'diagnosis', 'diagnosisDate', 'dominant_hand', 'ethnicity', 'gender', 'givenName', 'postcode', 'surname'];
        for (let i = 0; i < fieldCheck.length; i++) {
            if (this.state[fieldCheck[i]] === 0 || this.state[fieldCheck[i]] === null || this.state[fieldCheck[i]] === '' || this.state[fieldCheck[i]] === 'unselected') {
                this.setState({ error: 'None of the fields can be empty!' });
                return;
            }
        }

        const DOBValidator = this.state.DOB ? this.state.DOB.isValid() : false;
        const diagnosisDateValidator = this.state.diagnosisDate ? this.state.diagnosisDate.isValid() : false;

        if (!DOBValidator || !diagnosisDateValidator) {
            this.setState({ error: 'Invalid dates provided' });
            return;
        }

        const demoData = {
            DOB: this.state.DOB.toISOString(),
            gender: this.state.gender,
            dominant_hand: this.state.dominant_hand,
            ethnicity: this.state.ethnicity,
            country_of_origin: this.state.country_of_origin
        };
        const PIIData = {
            firstName: this.state.givenName,
            surname: this.state.surname,
            fullAddress: this.state.address,
            postcode: this.state.postcode
        };
        const diagnosisData = {
            diagnosis: this.state.diagnosis,
            diagnosisDate: this.state.diagnosisDate.toISOString()
        };
        const patientData = {
            aliasId: this.state.aliasId,
            optimiseConsent: this.state.showConsentDatePicker === 'Y' ? this.state.optimiseConsentDate.toISOString() : null,
            pregnancySubStudyConsent: this.state.showPregnancyConsentDatePicker === 'Y' ? this.state.pregnancyConsentDate.toISOString() : null
        };
        const body = {
            patientData: patientData,
            demoData: demoData,
            patientId: this.state.aliasId,
            diagnosisData: diagnosisData,
            PIIData: PIIData
        };

        this.setState({
            lastSubmit: (new Date()).getTime()
        }, () => {
            store.dispatch(createPatientCall(body));
            this.setState({ dispatched: true });
        });

    }

    render() {
        if (!this.state.dispatched) {
            const { genders, dominant_hands, ethnicities, countries } = this.props.demofields;
            let genders_sorted = [];
            genders.forEach((el) => {
                el.value = el.value[0].toUpperCase() + el.value.slice(1).toLowerCase();
                genders_sorted.push(el);
            });
            let dominant_hands_sorted = [];
            dominant_hands.forEach((el) => {
                el.value = el.value[0].toUpperCase() + el.value.slice(1).toLowerCase();
                if (el.value === 'Unknown')
                    dominant_hands_sorted.unshift({
                        ...el,
                        value: ''
                    });
                else
                    dominant_hands_sorted.push(el);
            });
            return (
                <>
                    <div className={style.ariane}>
                        <h2>+ New Patient Profile</h2>
                        <BackButton to={'/searchPatient'} />
                    </div>
                    <div className={style.panel}>
                        <form onSubmit={this._handleSubmit}>
                            <label htmlFor='aliasId'>Patient ID:</label> <br /> <input value={this.state.aliasId} name='aliasId' onChange={this._handleFreeTextChange} autoComplete='off' /><br /><br />
                            <h4>Personal information</h4><br />
                            <label htmlFor='givenName'>Given name:</label><br /> <input value={this.state.givenName} name='givenName' onChange={this._handleFreeTextChange} autoComplete='off' /><br /><br />
                            <label htmlFor='surname'>Surname:</label><br /> <input value={this.state.surname} name='surname' onChange={this._handleFreeTextChange} autoComplete='off' /><br /><br />
                            <label htmlFor='address'>Full Address:</label><br /><input value={this.state.address} name='address' onChange={this._handleFreeTextChange} autoComplete='off' /><br /><br />
                            <label htmlFor='postcode'>Postcode:</label><br /> <input value={this.state.postcode} name='postcode' onChange={this._handleFreeTextChange} autoComplete='off' /><br /><br />
                            <br />
                            <h4>Consent</h4><br />
                            <label htmlFor='showConsentDatePicker'>Does the patient give consent for sharing:</label><br />
                            <select name='showConsentDatePicker' value={this.state.showConsentDatePicker} onChange={this._handleConsentChange} autoComplete='off'>
                                <option value='Y'>Yes</option>
                                <option value='N'>No</option>
                            </select><br /><br />
                            {
                                this.state.showConsentDatePicker === 'Y' ?
                                    <>
                                        <label>Consent date:</label>
                                        <PickDate startDate={this.state.optimiseConsentDate} handleChange={this._handleConsentDateChange} /> <br /><br />
                                    </>
                                    :
                                    null
                            }
                            <br />
                            <h4>Basic demographic data</h4><br />
                            <label>Date of birth:</label><br /> <PickDate startDate={this.state.DOB} handleChange={this._handleDobDateChange} /> <br /><br />
                            <label htmlFor='gender'>Gender:</label><br /> <SelectField name='gender' value={this.state.gender} options={genders_sorted} handler={this._handleChange} /> <br /><br />
                            {
                                this.state.gender !== 0 && this.state.gender !== 1 ?
                                    <>
                                        <h4>*Pregnancy sub study consent</h4><br />
                                        <label htmlFor='showPregnancyConsentDatePicker'>Does the patient give consent for sharing pregnancy data:</label><br />
                                        <select name='showPregnancyConsentDatePicker' value={this.state.showPregnancyConsentDatePicker} onChange={this._handlePregnancyConsentChange} autoComplete='off'>
                                            <option value='Y'>Yes</option>
                                            <option value='N'>No</option>
                                        </select><br /><br />
                                        {
                                            this.state.showPregnancyConsentDatePicker === 'Y' ?
                                                <>
                                                    <label>Consent date:</label>
                                                    <PickDate startDate={this.state.pregnancyConsentDate} handleChange={this._handlePregnancyConsentDateChange} /> <br /><br />
                                                </>
                                                :
                                                null
                                        }
                                    </>
                                    : null
                            }
                            <label htmlFor='dominant_hand'>Dominant hand:</label><br /> <SelectField name='dominant_hand' value={this.state['dominant_hand']} options={dominant_hands_sorted} handler={this._handleChange} noEmpty={true} /> <br /><br />
                            <label htmlFor='ethnicity'>Ethnicity:</label><br /> <SelectField name='ethnicity' value={this.state['ethnicity']} options={ethnicities} handler={this._handleChange} /> <br /><br />
                            <label htmlFor='country_of_origin'>Country of origin:</label><br /> <SelectField name='country_of_origin' value={this.state['country_of_origin']} options={countries} handler={this._handleChange} /> <br /><br />
                            <br />
                            <h4>Primary MS diagnosis</h4><br />
                            <label>Diagnosis date:</label><br /> <PickDate startDate={this.state.diagnosisDate} handleChange={this._handleDiagnosisDateChange} /> <br /><br />
                            <label htmlFor='diagnosis'>Diagnosis:</label><br /> <SelectField name='diagnosis' value={this.state['diagnosis']} options={this.props.diagnosesfields} handler={this._handleChange} /> <br /><br />
                            {this.state.error ? <><div className={style.error}>{this.state.error}</div><br /></> : null}
                            <button type="submit">Submit</button>
                        </form>
                        <br />
                    </div>
                </>
            );
        } else {
            return <Redirect to={`/patientProfile/${this.state.aliasId}`} />;
        }
    }
}


/**
* @prop {string} this.props.name - field name
* @prop {string} this.props.value - value (usually passed from state of parent)
* @prop {Array} this.props.options - list of options to be rendered; each option would be {id: x, value: 'abc'}
* @prop {Function} this.props.handler - event listener passed down by parent to change the state of parent
            */
export class SelectField extends Component {
    render() {
        return (
            <select onChange={this.props.handler} name={this.props.name} value={this.props.value} autoComplete='off'>
                {this.props.noEmpty !== true ? <option value={0}></option> : null}
                {this.props.options.map(el => <option key={el.id} value={el.id}>{el.value}</option>)}
            </select>
        );
    }
}

export default CreatePatient;