Upstream sync

This commit is contained in:
Senad Uka
2018-05-25 09:10:32 +02:00
parent 659160676c
commit 11fe5f1c61
14 changed files with 2296 additions and 121 deletions

View File

@@ -3,57 +3,60 @@ import Dialog from 'material-ui/Dialog';
import FlatButton from 'material-ui/FlatButton';
export class ValidationErrorsInfoDialog extends React.Component {
state = {
constructor(props) {
super(props)
this.props = props;
this.state = {
open: this.props.open,
}
componentWillReceiveProps(newProps){
this.setState({open: newProps.open});
}
handleOpen = () => {
this.setState({ open: true });
};
handleClose = () => {
this.setState({ open: false });
this.props.onDismiss();
};
render() {
const actions = [
<FlatButton
label="Dismiss"
primary={true}
keyboardFocused={true}
onClick={this.handleClose}
/>,
];
return (
<div>
<Dialog
title="Erors"
actions={actions}
modal={this.props.modal ? this.props.modal : false}
open={this.state.open}
onRequestClose={this.handleClose}
overlayStyle={{backgroundColor: 'transparent'}}
>
{this.props.errorMessages.map(errorMessage => {
return (
<div>
<a>{errorMessage.message}</a>
<br/>
</div>
);
})}
</Dialog>
</div>
);
}
}
module.exports = ValidationErrorsInfoDialog;
componentWillReceiveProps(newProps) {
this.setState({ open: newProps.open });
}
handleOpen = () => {
this.setState({ open: true });
};
handleClose = () => {
this.setState({ open: false });
this.props.onDismiss();
};
render() {
const actions = [
<FlatButton
label="Dismiss"
primary={true}
keyboardFocused={true}
onClick={this.handleClose}
/>,
];
return (
<div>
<Dialog
title="Errors"
actions={actions}
modal={this.props.modal ? this.props.modal : false}
open={this.state.open}
onRequestClose={this.handleClose}
overlayStyle={{ backgroundColor: 'transparent' }}
>
{this.props.errorMessages.map(errorMessage => {
return (
<div>
<a>{errorMessage.message}</a>
<br />
</div>
);
})}
</Dialog>
</div>
);
}
}
module.exports = ValidationErrorsInfoDialog;

View File

@@ -7,6 +7,7 @@ import {
loggedUser,
planScheduler,
providerScheduler,
visitReporter,
} from 'utils/authorization';
class SidebarContent extends React.Component {
@@ -66,7 +67,6 @@ class SidebarContent extends React.Component {
$subUl.stop().slideToggle(slideTime);
});
// HighlightActiveItems
const $links = $nav.find('a');
const currentLocation = hashHistory.getCurrentLocation();
@@ -101,27 +101,34 @@ class SidebarContent extends React.Component {
return (
<ul className="nav" ref={(c) => { this.nav = c; }}>
{loggedUser.anyOf(planScheduler, visitReporter) &&
<li><FlatButton className="prepend-icon" href={"#/app/form/visit/" + this.state.user.useruuid}><span>Create Visit</span></FlatButton></li>
}
{!loggedUser.anyOf(planScheduler, visitReporter) &&
<li>
<FlatButton href="#/app/form"><i className="nav-icon material-icons cyan-text text-lighter-4">directions_car</i><span className="nav-text">Rides</span></FlatButton>
<ul>
<li><FlatButton className="prepend-icon" href={"#/app/form/steppers/" + this.state.user.useruuid}><span>Book Rides</span></FlatButton></li>
<li><FlatButton className="prepend-icon" href="#/app/table/rides"><span>Manage Rides</span></FlatButton></li>
</ul>
</li>
}
{!loggedUser.anyOf(planScheduler, visitReporter) &&
<li>
<FlatButton href="#/app/chart"><i className="nav-icon material-icons">people_outline</i><span className="nav-text">Members</span></FlatButton>
<ul>
<li><FlatButton className="prepend-icon" href="#/app/page/eligibility"><span>Verify Eligibility</span></FlatButton></li>
<li><FlatButton className="prepend-icon" href="#/app/table/members"><span>Manage Members</span></FlatButton></li>
</ul>
</li>
}
<li>
<FlatButton href="#/app/form"><i className="nav-icon material-icons cyan-text text-lighter-4">directions_car</i><span className="nav-text">Rides</span></FlatButton>
<FlatButton href="#/app/chart"><i className="nav-icon material-icons">schedule</i><span className="nav-text">Visits</span></FlatButton>
<ul>
<li><FlatButton className="prepend-icon" href={"#/app/form/steppers/" + this.state.user.useruuid}><span>Book Rides</span></FlatButton></li>
<li><FlatButton className="prepend-icon" href="#/app/table/rides"><span>Manage Rides</span></FlatButton></li>
<li><FlatButton className="prepend-icon" href={"#/app/form/visit/" + this.state.user.useruuid}><span>Create Visit</span></FlatButton></li>
<li> <FlatButton className="prepend-icon" href="#/app/table/visits"><span className="nav-text">Manage Visits</span></FlatButton></li>
</ul>
</li>
<li>
<FlatButton href="#/app/chart"><i className="nav-icon material-icons">people_outline</i><span className="nav-text">Members</span></FlatButton>
<ul>
<li><FlatButton className="prepend-icon" href="#/app/page/eligibility"><span>Verify Eligibility</span></FlatButton></li>
<li><FlatButton className="prepend-icon" href="#/app/table/members"><span>Manage Members</span></FlatButton></li>
</ul>
</li>
<li>
<FlatButton href="#/app/table/visits"><i className="nav-icon material-icons">schedule</i><span className="nav-text">Visits</span></FlatButton>
</li>
{/* <li>
<FlatButton href="#/app/table/message"><i className="nav-icon material-icons">mail_outline</i><span className="nav-text">Message Center</span></FlatButton>
</li> */}
<li>
<FlatButton href="#/app/chart"><i className="nav-icon material-icons">settings</i><span className="nav-text">Manage</span></FlatButton>

View File

@@ -202,28 +202,30 @@ export class NEMTLocation extends React.Component {
Instance.getRawConn().get(`/v1/nemt/provider/participating?sort=distance&lat=${lat}&long=${long}`).then(res => {
let nearByPlaces = [];
let providers = res.data.map(p => {
const streetNumber = p.address.street_address_1.split(' ')[0]
let clickResult = {
id: p.muk_id,
address: `${p.address.street_address_1}, ${p.address.city}, ${p.address.state} (${p.address.zipcode})`,
lat: p.address.lat,
lng: p.address.long,
name: p.name,
type: "provider",
raw: p,
street_number: streetNumber,
street: p.address.street_address_1.replace(streetNumber, '').trim(),
city: p.address.city,
state: p.address.state,
zipcode: p.address.zipcode.substring(0, 5),
country: p.address.country,
saved: false,
}
clickResult.address = `${clickResult.street_number} ${clickResult.street}, ${clickResult.city}`
if (p.address.street_address_1) {
const streetNumber = p.address.street_address_1.split(' ')[0]
let clickResult = {
id: p.muk_id,
address: `${p.address.street_address_1}, ${p.address.city}, ${p.address.state} (${p.address.zipcode})`,
lat: p.address.lat,
lng: p.address.long,
name: p.name,
type: "provider",
raw: p,
street_number: streetNumber,
street: p.address.street_address_1.replace(streetNumber, '').trim(),
city: p.address.city,
state: p.address.state,
zipcode: p.address.zipcode.substring(0, 5),
country: p.address.country,
saved: false,
}
clickResult.address = `${clickResult.street_number} ${clickResult.street}, ${clickResult.city}`
var listItem = (<ListItem primaryText={p.name} secondaryText={clickResult.address} key={p.muk_id} rightIcon={<MapsLocalHospital />} onClick={(event) => this.handlePlaceChanged(clickResult)} />)
nearByPlaces.push(listItem);
p.providerText = `${p.name} - ${p.address.street_address_1}, ${p.address.city}, ${p.address.state} (${p.address.zipcode}) (${p.address.phone_number})`
var listItem = (<ListItem primaryText={p.name} secondaryText={clickResult.address} key={p.muk_id} rightIcon={<MapsLocalHospital />} onClick={(event) => this.handlePlaceChanged(clickResult)} />)
nearByPlaces.push(listItem);
p.providerText = `${p.name} - ${p.address.street_address_1}, ${p.address.city}, ${p.address.state} (${p.address.zipcode}) (${p.address.phone_number})`
}
return p;
});
@@ -461,7 +463,7 @@ export class NEMTLocation extends React.Component {
this.setState(Object.assign(this.state, { open: true }));
if (this.state.user.useruuid === '' || this.state.user.useruuid !== this.props.data.user.useruuid) {
if (this.props.data.user && this.props.data.user !== null && this.props.data.user.useruuid !== '') {
if (this.props.data.user && this.props.data.user.useruuid !== undefined && this.props.data.user !== null && this.props.data.user.useruuid !== '') {
let url = `/v1/nemt/users/member/` + this.props.data.user.useruuid
Instance.getRawConn().get(url).then(res => {
let user = res.data;

View File

@@ -6,6 +6,8 @@ module.exports = {
require('./routes/components'),
require('./routes/layouts'),
require('./routes/steppers'),
require('./routes/visitRide'),
require('./routes/visit'),
]);
});
}

View File

@@ -405,8 +405,8 @@ class VerticalNonLinear extends React.Component {
},
return_time: new Date(),
pickupTimeHide: false,
showValidationErrors:false,
validationErrors:[],
showValidationErrors: false,
validationErrors: [],
};
}
@@ -451,19 +451,19 @@ class VerticalNonLinear extends React.Component {
}
});
let date = new Date();
let date = new Date();
let visitTime = new Date(Math.round((date.getTime() + (1 * 60 * 60 * 1000)) / roundingTime) * roundingTime);
let visitDate = date;
let pickupTime = new Date(Math.round((visitTime.getTime() - (0.5 * 60 * 60 * 1000)) / roundingTime) * roundingTime);
let pickupTimeReturn = new Date(Math.round((visitTime.getTime() - (0.5 * 60 * 60 * 1000)) / roundingTime) * roundingTime);
this.setState(Object.assign(this.state, {
visitDate: visitDate,
visitTime: visitTime,
pickupTime: pickupTime,
pickupTimeReturn: pickupTimeReturn,
}));
let visitTime = new Date(Math.round((date.getTime() + (1 * 60 * 60 * 1000)) / roundingTime) * roundingTime);
let visitDate = date;
let pickupTime = new Date(Math.round((visitTime.getTime() - (0.5 * 60 * 60 * 1000)) / roundingTime) * roundingTime);
let pickupTimeReturn = new Date(Math.round((visitTime.getTime() - (0.5 * 60 * 60 * 1000)) / roundingTime) * roundingTime);
this.setState(Object.assign(this.state, {
visitDate: visitDate,
visitTime: visitTime,
pickupTime: pickupTime,
pickupTimeReturn: pickupTimeReturn,
}));
}
//for snackbar
handleTouchTap() {
@@ -521,11 +521,11 @@ class VerticalNonLinear extends React.Component {
self.handleRequestClose(self);
window.location.href = '/#/app/page/map/' + res.data.ride_uuid;
}).catch(error => {
if (error.response.status === 422){
if (error.response.status === 422) {
//Unprocessable Entity (validation failed)
self.setState(Object.assign(self.state, {
showValidationErrors:true,
validationErrors:error.response.data.data
showValidationErrors: true,
validationErrors: error.response.data.data
}));
}
});
@@ -815,9 +815,9 @@ class VerticalNonLinear extends React.Component {
}
handleValidationErrosDialogDismiss(){
handleValidationErrosDialogDismiss() {
this.setState(Object.assign(this.state, {
showValidationErrors:false
showValidationErrors: false
}));
}
@@ -860,16 +860,18 @@ class VerticalNonLinear extends React.Component {
if (this.state.showUserSelection && this.state.users.length > 0) {
const handleAutocomplete = (u) => {
let userHomeAddress = null;
if (u.addresses && u.addresses.length > 0) {
u.addresses.forEach(address => {
if (address.address_type === ADDRESS_TYPE_HOME) {
userHomeAddress = address;
}
});
if (userHomeAddress != null) {
userHomeAddress.name = "Home";
state.handlePickupChanged(userHomeAddress,state);
}
state.setState(Object.assign(state.state, { user: u, userSelectionText: u.userdata }));
}
if (userHomeAddress != null) {
userHomeAddress.name = "Home";
state.handlePickupChanged(userHomeAddress, state);
}
state.setState(Object.assign(state.state, { user: u, userSelectionText: u.userdata }));
}
const datasourceConfig = { text: 'userdata', value: 'useruuid' }
userSelection = (
@@ -894,8 +896,8 @@ class VerticalNonLinear extends React.Component {
<div className="box-body padding-xs">
<div style={{ maxWidth: 380, margin: 'auto' }}>
<ValidationErrorsInfoDialog open = {this.state.showValidationErrors} errorMessages = {this.state.validationErrors} onDismiss={this.handleValidationErrosDialogDismiss.bind(this)}/>
<ValidationErrorsInfoDialog open={this.state.showValidationErrors} errorMessages={this.state.validationErrors} onDismiss={this.handleValidationErrosDialogDismiss.bind(this)} />
<Stepper
activeStep={this.state.stepIndex}
linear={false}

View File

@@ -0,0 +1,14 @@
import React from 'react';
import QueueAnim from 'rc-queue-anim';
import VerticalNonLinear from './VerticalNonLinear';
const Stepper = (props) => {
return (
<div className="container-fluid with-maxwidth chapter">
<QueueAnim type="bottom" className="ui-animate">
<div key="1"><VerticalNonLinear params={props.params} /></div>
</QueueAnim>
</div>
);
};
module.exports = Stepper;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
module.exports = {
path: 'visit/:uuid',
getComponent(nextState, cb) {
require.ensure([], (require) => {
cb(null, require('./components/Steppers'));
});
}
};

View File

@@ -0,0 +1,14 @@
import React from 'react';
import QueueAnim from 'rc-queue-anim';
import VerticalNonLinear from './VerticalNonLinear';
const Stepper = (props) => {
return (
<div className="container-fluid with-maxwidth chapter">
<QueueAnim type="bottom" className="ui-animate">
<div key="1"><VerticalNonLinear params={props.params} /></div>
</QueueAnim>
</div>
);
};
module.exports = Stepper;

View File

@@ -0,0 +1,910 @@
import React, { Component } from 'react';
import {
Step,
Stepper,
StepButton,
StepContent,
} from 'material-ui/Stepper';
import RaisedButton from 'material-ui/RaisedButton';
import FlatButton from 'material-ui/FlatButton';
import QueueAnim from 'rc-queue-anim';
import { RadioButton, RadioButtonGroup } from 'material-ui/RadioButton';
import ActionFavorite from 'material-ui/svg-icons/action/favorite';
import ActionFavoriteBorder from 'material-ui/svg-icons/action/favorite-border';
import AutoComplete from 'material-ui/AutoComplete';
import SelectField from 'material-ui/SelectField';
import MenuItem from 'material-ui/MenuItem';
import { Tabs, Tab } from 'material-ui/Tabs';
// import Slider from 'material-ui/Slider';
import TimePicker from 'material-ui/TimePicker';
import DatePicker from 'material-ui/DatePicker';
import TextField from 'material-ui/TextField';
// import Toggle from 'material-ui/Toggle';
import Snackbar from 'material-ui/Snackbar';
import { NEMTLocation } from '../../../../../components/NEMTLocation';
import { request } from 'https';
import Divider from 'material-ui/Divider';
import Paper from 'material-ui/Paper';
import Dialog from 'material-ui/Dialog';
import Close from 'material-ui/svg-icons/navigation/close'
import CommunicationCall from 'material-ui/svg-icons/communication/call'
import Message from 'material-ui/svg-icons/communication/message'
import Instance from '../../../../../../../components/Connection';
import ValidationErrorsInfoDialog from '../../../../../../../components/Shared/ValidationErrorsInfoDialog';
import Checkbox from 'material-ui/Checkbox';
import Popover from 'material-ui/Popover';
let DateTimeFormat;
const roundingTime = 1000 * 60 * 5; //5 minutes
DateTimeFormat = global.Intl.DateTimeFormat;
class SignUp extends React.Component {
constructor(props) {
super(props);
this.props = props;
}
componentWillReceiveProps = (nextProps) => {
this.props = nextProps;
}
handleEmail = (event) => {
if (this.props.onUserChanged) {
const user = this.props.user;
user.email = event.target.value;
this.props.onUserChanged(user);
}
};
handlePhone = (event) => {
let phone = event.target.value;
if (phone.indexOf("+1") < 0 && phone.length == 10) {
phone = "+1" + phone;
phone = phone.substring(0, 12);
}
if (this.props.onUserChanged) {
const user = this.props.user;
user.phonenumber = event.target.value;
this.props.onUserChanged(user);
}
};
render() {
return (
<form className="">
<fieldset>
{/* <div className="form-group"> */}
<TextField
floatingLabelText="First Name"
value={this.props.user.first}
disabled={true}
/>
<TextField
floatingLabelText="Last Name"
value={this.props.user.last}
disabled={true}
/>
<TextField
floatingLabelText="Email"
type="email"
value={this.props.user.email}
onChange={this.handleEmail}
/>
<SelectField
floatingLabelText="Gender"
value={this.props.user.gender}
disabled={true}
>
<MenuItem value={null} primaryText="" />
<MenuItem value={"M"} primaryText="Male" />
<MenuItem value={"F"} primaryText="Female" />
<MenuItem value={"U"} primaryText="Unknown" />
</SelectField>
<SelectField
style={{ maxWidth: 165 }}
floatingLabelText="Member Type"
value={"S"}
disabled={true}
>
<MenuItem value={null} primaryText="" />
<MenuItem value={"S"} primaryText="Subscriber" />
<MenuItem value={"D"} primaryText="Dependant" />
<MenuItem value={"U"} primaryText="Unknown" />
</SelectField>
<TextField
style={{ maxWidth: 165 }}
floatingLabelText="Member #"
value={this.props.user.member}
disabled={true}
/>
<DatePicker width="115" hintText="Birth Date" container="inline" style={{ width: 115 }}
value={this.props.user.birthdate} disabled={true} />
<TextField
style={{ maxWidth: 115 }}
floatingLabelText="Mobile Phone"
type="telephone"
value={this.props.user.phonenumber}
onChange={this.handlePhone}
/>
</fieldset>
</form>
);
}
}
export class AdditionalPassengerSelect extends React.Component {
state = {
open: false,
additionalPassenger:
{
passengerType: '',
seatType: '',
}
};
handleOpen = () => {
this.setState({ open: true });
};
handlePassengerTypeChange = (e, i, v, state) => {
this.setState({ additionalPassenger: { passengerType: v } });
};
handleSeatTypeChange = (e, i, v, state) => {
this.setState({ additionalPassenger: { seatType: v } });
};
handleClose = () => {
this.setState({ open: false });
};
render() {
const actions = [
<FlatButton
label="Add"
primary={true}
keyboardFocused={true}
onClick={this.handleClose}
/>,
<FlatButton
label="Cancel"
primary={false}
keyboardFocused={false}
onClick={this.handleClose}
/>,
];
return (
<div>
<RaisedButton style={{ fontSize: 5 }} label="+ Passenger" onClick={this.handleOpen} />
<Dialog
title="Add Passenger"
actions={actions}
modal={false}
open={this.state.open}
onRequestClose={this.handleClose}
>
<SelectField
floatingLabelText="Passenger Type"
value={this.state.additionalPassenger.passengerType}
onChange={(e, i, v) => this.handlePassengerTypeChange(e, i, v, this)}
autoWidth={true}
>
<MenuItem value={'Caregiver'} primaryText="Caregiver" />
<MenuItem value={'Companion'} primaryText="Companion" />
<MenuItem value={'Additional Patient'} primaryText="Additional Patient" />
</SelectField>
<SelectField
floatingLabelText="Seat Type"
value={this.state.additionalPassenger.seatType}
onChange={(e, i, v) => this.handleSeatTypeChange(e, i, v, this)}
autoWidth={true}
>
<MenuItem value={'Ambulatory'} primaryText="Ambulatory" />
<MenuItem value={'Stretcher'} primaryText="Stretcher" />
<MenuItem value={'Wheelchair'} primaryText="Wheelchair" />
</SelectField>
</Dialog>
</div>
);
}
}
const names = [
'Service Animal',
'Cane / Quad Cane',
'Electric Wheelchair',
'Oxygen Tank',
'Sign Language',
'White Cane',
'Leg Braces',
'Crutches',
'Manual Wheelchair',
'Prothesis',
'Walker',
];
export class MobilitySelect extends Component {
state = {
values: [],
};
handleChange = (event, index, values) => this.setState({ values });
menuItems(values) {
return names.map((name) => (
<MenuItem
key={name}
insetChildren={true}
checked={values && values.indexOf(name) > -1}
value={name}
primaryText={name}
autoWidth={false}
style={{ width: 215 }}
/>
));
}
render() {
const { values } = this.state;
return (
<SelectField
autoWidth={false}
style={{ width: 215 }}
multiple={true}
value={values}
floatingLabelText="Mobility Aids"
label="Mobility Aids"
onChange={this.handleChange}
>
{this.menuItems(values)}
</SelectField>
);
}
}
const selectStyles = {
customWidth: {
width: 35,
},
};
var tripType = 'To Visit';
var pickupTimeReturnDisplayMode = "none";
export class RideTypeSelect extends Component {
constructor(props) {
super(props);
this.props = props;
this.state = {
value: 'to_visit',
pickupTimeReturnDisplayMode: 'none',
pickupTimeHide: false,
};
}
componentDidMount() {
this.setState(Object.assign(this.state, { value: this.props.value }));
}
handleChange(event, index, value, state) {
let self = state
tripType = value;
switch (tripType) {
case 'from_visit':
pickupTimeReturnDisplayMode = "none"
self.setState(Object.assign(self.state, { pickupTimeReturnDisplayMode: 'none', value: 'from_visit', pickupTimeHide: false }));
break;
case 'from_visit_call':
pickupTimeReturnDisplayMode = "none"
self.setState(Object.assign(self.state, { pickupTimeReturnDisplayMode: 'none', value: 'from_visit_call', pickupTimeHide: true }));
break;
case 'to_visit':
pickupTimeReturnDisplayMode = "none"
self.setState(Object.assign(self.state, { pickupTimeReturnDisplayMode: 'none', value: 'to_visit', pickupTimeHide: false }));
break;
case 'roundtrip':
pickupTimeReturnDisplayMode = "block"
self.setState(Object.assign(self.state, { pickupTimeReturnDisplayMode: 'block', value: 'roundtrip', pickupTimeHide: false }));
break;
case 'roundtrip_call':
pickupTimeReturnDisplayMode = "none";
self.setState(Object.assign(self.state, { pickupTimeReturnDisplayMode: 'none', value: 'roundtrip_call', pickupTimeHide: false }));
break;
default:
self.setState(Object.assign(self.state, { pickupTimeReturnDisplayMode: 'block', value: 'roundtrip', pickupTimeHide: false }));
break;
}
if (this.props.handleChange) {
this.props.handleChange(event, index, { pickupTimeReturnDisplayMode: self.state.pickupTimeReturnDisplayMode, selectField: this.state.value, pickupTimeHide: this.state.pickupTimeHide });
}
}
render() {
return (
<div >
<SelectField
floatingLabelText="Trip Type"
value={this.state.value}
onChange={(e, i, v) => this.handleChange(e, i, v, this)}
autoWidth={false}
style={{ width: 230 }}
>
<MenuItem value={'to_visit'} primaryText="To Visit" />
<MenuItem value={'from_visit'} primaryText="From Visit" />
<MenuItem value={'from_visit_call'} primaryText="From Visit / Will Call" />
<MenuItem value={'roundtrip'} primaryText="Round Trip" />
<MenuItem value={'roundtrip_call'} primaryText="Round Trip / Will Call" />
</SelectField>
</div>
);
}
}
function disableWeekends(date) {
return date.getDay() === 0 || date.getDay() === 6;
}
const styles = {
padding: '12px 18px',
marginBottom: 12,
fontWeight: 400,
maxWidth: 250,
radioButton: {
marginTop: 6
},
checkbox: {
marginTop: 16, fontWeight: 100, fontSize: 10
},
};
function handleActive(tab) {
console.log(`A tab with this route property ${tab.props.route} was activated.`);
}
const
dataConfig = { text: 'text', value: 'value' };
/**
* A basic vertical non-linear implementation
*/
class VerticalNonLinear extends React.Component {
constructor(props) {
super(props);
let dateNow = new Date();
this.state = {
stepIndex: 0,
rideTypeValue: 0,
providerID: 0,
providerName: '',
visitDate: new Date(),
visitTime: new Date(Math.round(dateNow.getTime() / roundingTime) * roundingTime),
pickupLocation: null,
pickupTime: new Date(Math.round(dateNow.getTime() / roundingTime) * roundingTime),
pickupTimeReturn: new Date(Math.round(dateNow.getTime() / roundingTime) * roundingTime),
pickupTimeReturnDisplayMode: 'none',
open: false,
message: 'Booking Ride',
origin: {},
destination: {},
buttonPickupText: 'Member Address',
buttodDropOffText: 'Choose Drop-Off location',
buttonProviderText: 'Choose Provider',
user: null,
showUserSelection: true,
userSelectionText: '',
users: [],
visit_external_id: "",
notes: "",
pickupTimeReturnDisplayMode: "none",
eta: {
distance_miles: 0,
duration_seconds: 0,
formatted_time: 0,
showed: false,
},
trip_type: {
key: "to_visit",
value: ""
},
return_time: new Date(),
pickupTimeHide: false,
showValidationErrors: false,
validationErrors: [],
visit: {
visit_uuid: "",
visit_status: {
key: "",
value: ""
},
user: {
useruuid: "",
name: "",
first: "",
last: "",
gender: "",
member: "",
birthdate: new Date(),
email: "",
phonenumber: ""
},
visit_datetime: new Date(),
pickup_datetime: new Date(),
notes: "",
pickup_address_id: 33,
pickup: {
id: ""
},
provider: {
provider_uuid: "",
internal_id: "",
muk_id: "",
name: "",
address: {
street_address_1: "",
city: "",
state: "",
zipcode: "",
country: "",
lat: 0,
long: 0,
phone_number: ""
},
organization: {
id: "",
type: {
name: "",
key: ""
},
name: "",
main: false,
active: false,
blocked: false,
suspended: false,
contacts: [],
addresses: []
}
},
trip_type: {
key: "",
value: ""
},
visit_external_id: ""
}
};
this.handleUser = this.handleUser.bind(this);
}
componentDidMount() {
let self = this;
let visit = {
uuid: this.props.params.uuid
}
Instance.getRawConn().get(`/v1/nemt/visits/${visit.uuid}`)
.then(function (res) {
const visit = res.data;
visit.user.birthdate = new Date(visit.user.birthdate);
visit.visit_datetime = new Date(visit.visit_datetime);
self.setState(Object.assign(self.state, { visit: visit }));
})
.catch(err => {
if (err.response.status !== 422) {
console.error(err);
}
});
}
//for snackbar
handleTouchTap() {
this.setState(Object.assign(this.state, {
open: true,
}));
};
handleRequestClose(state) {
let self = state;
self.setState(Object.assign(self.state, {
open: false,
}));
};
handleNext(state) {
let self = state;
const { stepIndex } = self.state;
if (stepIndex < 4) {
self.setState(Object.assign(self.state, { stepIndex: stepIndex + 1 }));
if (stepIndex === 3) {
self.handleTouchTap();
const visitRide = {
visit: self.state.visit,
trip_type: self.state.trip_type,
pickup_time: self.state.pickupTime,
return_time: self.state.return_time,
notes: self.state.notes,
};
if (self.diffMinutes(self.state.pickupTime, new Date()) > 10) {
visitRide.scheduled_pickup_range = {
range_ms: null,
timestamp_ms: new Date(self.state.pickupTime).getTime()
}
}
Instance.getRawConn().post(`/v1/nemt/visits/${self.state.visit.visit_uuid}/ride`, visitRide).then(function (res) {
window.location.href = '/#/app/page/map/' + res.data.ride_uuid;
}).catch(error => {
if (error.response.status === 422) {
self.setState(Object.assign(self.state, {
showValidationErrors: true,
validationErrors: error.response.data.data
}));
}
});
}
}
};
diffMinutes(dt2, dt1) {
var diff = (dt2.getTime() - dt1.getTime()) / 1000;
diff /= 60;
return Math.abs(Math.round(diff));
}
handlePrev(state) {
let self = state;
const { stepIndex } = self.state;
if (stepIndex > 0) {
self.setState(Object.assign(self.state, { stepIndex: stepIndex - 1 }));
}
};
handleChange(value, state) {
let self = state
self.setState(Object.assign(self.state, {
rideTypeValue: parseInt(value.target.defaultValue)
}));
};
handleDate(event, date, state) {
let self = state
let visitTime = new Date(Math.round((date.getTime() + (1 * 60 * 60 * 1000)) / roundingTime) * roundingTime);
let visitDate = date;
let pickupTime = new Date(Math.round((visitTime.getTime() - (0.5 * 60 * 60 * 1000)) / roundingTime) * roundingTime);
let pickupTimeReturn = new Date(Math.round((visitTime.getTime() - (0.5 * 60 * 60 * 1000)) / roundingTime) * roundingTime);
self.setState(Object.assign(self.state, {
visitDate: visitDate,
visitTime: visitTime,
pickupTime: pickupTime,
pickupTimeReturn: pickupTimeReturn,
}));
}
handleTime(value, date, state) {
let self = state;
self.setState(Object.assign(self.state, {
visitDate: date,
visitTime: date,
pickupTime: new Date(date.getTime() - (0.5 * 60 * 60 * 1000)),
pickupTimeReturn: new Date(date.getTime() - (0.5 * 60 * 60 * 1000)),
}));
}
handlePickupTime(value, date, state) {
let self = state;
console.log('Pickup Time', date);
self.setState(Object.assign(self.state, {
pickupTime: date,
pickupTimeReturn: date
}));
}
handlePickupTimeReturn(value, date, state) {
let self = state;
self.setState(Object.assign(self.state, {
return_time: date,
pickupTimeReturn: date,
pickupTimeReturnDisplayMode: 'block'
}));
}
handlePickup(value) {
console.log(value);
this.setState(Object.assign(this.state, {
pickupLocation: value.text
}));
};
handleNotes(e, value, state) {
let self = state
self.setState(Object.assign(self.state, {
notes: value
}));
}
handleChangeVisitType(event, index, value, state) {
let self = state;
let trip_type = {
key: value.selectField,
}
self.setState(Object.assign(self.state, { pickupTimeReturnDisplayMode: value.pickupTimeReturnDisplayMode, trip_type: trip_type, pickupTimeHide: value.pickupTimeHide }));
}
renderStepActions(step, state) {
let self = state;
return (
<div style={{ margin: '12px 0' }}>
{step !== 2 && (
<RaisedButton
label="Next"
disableTouchRipple
disableFocusRipple
primary
onTouchTap={() => self.handleNext(self)}
style={{ marginRight: 12 }}
/>
)}
{step === 2 && (
<RaisedButton
label="Confirm"
disableTouchRipple
disableFocusRipple
primary
onTouchTap={() => self.handleNext(self)}
style={{ marginRight: 12 }}
href=""
/>
)}
{step > 0 && (
<FlatButton
label="Back"
disableTouchRipple
disableFocusRipple
onTouchTap={() => self.handlePrev(self)}
/>
)}
</div>
);
}
handleValidationErrosDialogDismiss() {
this.setState(Object.assign(this.state, {
showValidationErrors: false
}));
}
handleUser(user) {
const visit = this.state.visit;
visit.user = user;
this.setState(Object.assign(this.state, { visit: visit }));
console.log(user);
}
render() {
const state = this;
let userSelection;
let pickupTimeSelector;
if (this.state.pickupTimeReturnDisplayMode !== 'none') {
pickupTimeSelector = (
<TimePicker
autoWidth={false}
style={{ width: 80, display: pickupTimeReturnDisplayMode }}
format="ampm"
underlineShow={true}
hintText="Choose Return Time"
floatingLabelText="Return Time"
value={this.state.pickupTimeReturn}
onChange={(e, d) => this.handlePickupTimeReturn(e, d, this)}
minutesStep={5}
/>)
}
let pickupTime = (<TimePicker
autoWidth={false}
style={{ width: 80 }}
format="ampm"
underlineShow={true}
hintText="Choose Pickup Time"
floatingLabelText="Pickup Time"
value={this.state.pickupTime}
onChange={(e, d) => this.handlePickupTime(e, d, this)}
minutesStep={5}
/>);
if (this.state.pickupTimeHide) pickupTime = null;
if (this.state.showUserSelection && this.state.users.length > 0) {
const handleAutocomplete = (u) => {
let userHomeAddress = null;
u.addresses.forEach(address => {
if (address.address_type === ADDRESS_TYPE_HOME) {
userHomeAddress = address;
}
});
if (userHomeAddress != null) {
userHomeAddress.name = "Home";
state.handlePickupChanged(userHomeAddress, state);
}
state.setState(Object.assign(state.state, { user: u, userSelectionText: u.userdata }));
}
const datasourceConfig = { text: 'userdata', value: 'useruuid' }
userSelection = (
<div>
<AutoComplete style={{ fontSize: '10' }} dataSourceConfig={datasourceConfig} dataSource={this.state.users} floatingLabelText="Choose Member" filter={(searchText, key) => (key.toLowerCase().indexOf(searchText.toLowerCase()) !== -1)} maxSearchResults={5} onNewRequest={handleAutocomplete} searchText={this.state.userSelectionText} />
</div>
);
} else if (this.state.showUserSelection && this.state.users.length === 0) {
userSelection = (<div style={{ fontSize: '10' }} >
<strong>Loading...</strong>
</div>);
} else {
userSelection = (<div >
<strong>{this.state.user.member}</strong> - {this.state.user.name}
</div>);
}
return (
<article className="article padding-sm-v">
<h2 className="article-title" style={{ paddingTop: 10, margin: 0 }} >Book Ride from Visit</h2>
<div className="box box-default">
<div className="box-body padding-xs">
<div style={{ maxWidth: 380, margin: 'auto' }}>
<ValidationErrorsInfoDialog open={this.state.showValidationErrors} errorMessages={this.state.validationErrors} onDismiss={this.handleValidationErrosDialogDismiss.bind(this)} />
<Stepper
activeStep={this.state.stepIndex}
linear={false}
orientation="vertical"
>
<Step>
<StepButton onClick={() => this.setState({ stepIndex: 0 })}>
Member
</StepButton>
<StepContent>
<form role="form">
<SignUp user={this.state.visit.user} onUserChanged={this.handleUser} />
</form>
{this.renderStepActions(0, this)}
</StepContent>
</Step>
<Step>
<StepButton onClick={() => this.setState({ stepIndex: 1 })}>
Provider
</StepButton>
<StepContent>
<form role="form">
{this.state.visit.provider.name}<br />
{this.state.visit.provider.address.street_address_1}<br />
{this.state.visit.provider.address.city}, {this.state.visit.provider.address.state} ({this.state.visit.provider.address.zipcode.substr(0, 5)})
</form>
{this.renderStepActions(1, this)}
</StepContent>
</Step>
<Step>
<StepButton onClick={() => this.setState({ stepIndex: 2 })}>
Visit Details
</StepButton>
<StepContent>
<form role="form">
<div className="form-group">
<DatePicker formatDate={new DateTimeFormat('en-US', {
weekday: 'short',
day: 'numeric',
month: 'long',
year: 'numeric',
}).format} style={{ maxWidth: 80 }} hintText="Visit Date" floatingLabelText="Date" container="inline" onChange={(e, d) => this.handleDate(e, d, this)} shouldDisableDate={disableWeekends} value={this.state.visit.visit_datetime} disabled={true} />
<TimePicker
style={{ maxWidth: 80 }}
format="ampm"
hintText="Visit Time"
floatingLabelText="Time"
value={this.state.visit.visit_datetime}
onChange={(e, d) => this.handleTime(e, d, this)}
minutesStep={5} disabled={true}
/>
</div>
<div className="divider" />
<div className="form-group">
<TextField hintText="Visit External ID" disabled="true" floatingLabelText="External ID" onChange={(e, v) => this.handleExternalID(e, v, this)} value={this.state.visit.visit_external_id} disable={true} />
</div>
</form>
{/* <TabsSection /> */}
{this.renderStepActions(1, this)}
</StepContent>
</Step>
<Step>
<StepButton onClick={() => this.setState({ stepIndex: 3 })}>
Trip Details
</StepButton>
<StepContent>
<form>
<RideTypeSelect handleChange={(e, i, v) => this.handleChangeVisitType(e, i, v, this)} value={this.state.trip_type.key} />
{pickupTime}
{pickupTimeSelector}
<MobilitySelect />
<AdditionalPassengerSelect />
<TextField
underlineShow={true}
hintText="Notes for Driver"
floatingLabelText="Notes for Driver"
onChange={(e, v) => this.handleNotes(e, v, this)}
value={this.state.notes} multiLine={true}
maxlength={250}
rows={1}
/>
</form>
{this.renderStepActions(2, this)}
</StepContent>
</Step>
</Stepper>
</div>
<div style={{ maxWidth: 380, margin: 'auto' }}>
<div className="divider divider-xl" />
<div className="callout callout-info">
<p>Complete steps <strong>1 - 4</strong> to schedule your ride!</p>
</div>
</div>
</div>
</div>
<div>
<Snackbar
style={{ fontSize: '7' }}
open={this.state.open}
message={this.state.message}
// message="Booking Ride"
autoHideDuration={50000}
onRequestClose={() => this.handleRequestClose(this)}
/>
</div>
</article>
);
}
}
export default VerticalNonLinear;

View File

@@ -0,0 +1,8 @@
module.exports = {
path: 'visitride/:uuid',
getComponent(nextState, cb) {
require.ensure([], (require) => {
cb(null, require('./components/Steppers'));
});
}
};

View File

@@ -38,18 +38,22 @@ const getDTList = function (member) {
let list = [];
member.forEach((r, i) => {
let bookRide = '';
if (r.trip_type.key === 'no_trip') {
bookRide = (<a href={`/#/app/form/visitride/${r.visit_uuid}`}>Book Ride</a>)
}
list.push(
<tr key={r.visit_uuid}>
<td>{moment(r.visit_datetime).format('MM/DD/YYYY - h:mm a')}</td>
<td><a href={""}>{r.provider.name}</a></td>
<td><a href={"/#/app/member/" + r.user.useruuid}>{r.user.name}</a></td>
<td>{bookRide}</td>
<td><RoadTripLink rides={r.rides} isOpened={false} currentRide={null} visit={r} onRideClick={handleRide} /></td>
<td><a href={"/#/app/member/" + r.user.useruuid}>{r.user.member}</a></td>
{/* <td>{r.visit_status.value}</td> */}
<td>{r.provider.id}</td>
<td>{r.provider.provider_uuid}</td>
<td>{r.visit_uuid}</td>
<td>{r.visit_external_id}</td>
<td> <a href={""}>{r.created_user.name} </a></td>
<td>{moment(r.created).format('MM/DD/YYYY - h:mm a')}</td>
<td>{moment(r.updated).format('MM/DD/YYYY - h:mm a')}</td>
@@ -232,11 +236,10 @@ class DatatableComponent extends React.Component {
<th>Visit Time</th>
<th>Provider</th>
<th>Member </th>
<th>Ride</th>
<th>Rides </th>
<th>Subscriber ID</th>
{/* <th>Status</th> */}
<th>Provider ID</th>
<th>Visit ID</th>
<th>External ID</th>
<th>Scheduler</th>

View File

@@ -14,5 +14,6 @@ export { default as providerScheduler } from './profiles/providerScheduler';
export { default as superAdmin } from './profiles/superAdmin';
export { default as support } from './profiles/support';
export { default as techsupportAdmin } from './profiles/techsupportAdmin';
export { default as visitReporter } from './profiles/visitReporter';
export default authorization;

View File

@@ -0,0 +1,7 @@
import authorization from '../authorization';
const visitReporter = authorization({
VIRPT: ['provider'],
});
export default visitReporter;