packages/optimise-ui/src/components/createPatient/createPatient.jsx
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;