File: /var/www/html/punjabcabs/public/asset/js/dispatcher-admin.js
'use strict';
class DispatcherPanel extends React.Component {
componentWillMount() {
this.setState({
listContent: 'dispatch-map'
});
}
handleUpdateBody(body) {
//console.log('Body Update Called', body);
this.setState({
listContent: body
});
}
handleUpdateFilter(filter) {
//console.log('Filter Update Called', this.state.listContent);
this.setState({
listContent: 'dispatch-map'
});
}
handleRequestShow(trip) {
// console.log('Show Request', trip);
if(trip.current_provider_id == 0) {
this.setState({
listContent: 'dispatch-assign',
trip: trip
});
} else {
this.setState({
listContent: 'dispatch-map',
trip: trip
});
}
ongoingInitialize(trip);
setTimeout(worldMapInitialize, 50000);
}
handleRequestcomplete(trip) {
location.reload(true);
}
handleRequestCancel(argument) {
this.setState({
listContent: 'dispatch-map'
});
}
render() {
let listContent = null;
// console.log('DispatcherPanel', this.state.listContent);
switch(this.state.listContent) {
case 'dispatch-create':
listContent = <div className="col-md-4">
<DispatcherRequest completed={this.handleRequestcomplete.bind(this)} cancel={this.handleRequestCancel.bind(this)} />
</div>;
break;
case 'dispatch-map':
listContent = <div className="col-md-4">
<DispatcherList clicked={this.handleRequestShow.bind(this)} />
</div>;
break;
case 'dispatch-assign':
listContent = <div className="col-md-4">
<DispatcherAssignList trip={this.state.trip} />
</div>;
break;
case 'driver-list':
listContent = <div className="col-md-4">
<DriverList/>
</div>;
break;
}
return (
<div className="container-fluid">
<DispatcherNavbar body={this.state.listContent} updateBody={this.handleUpdateBody.bind(this)} updateFilter={this.handleUpdateFilter.bind(this)} cancelback={this.handleRequestCancel.bind(this)}/>
<div className="row margin-dispatch">
{ listContent }
<div className="col-md-8">
<DispatcherMap body={this.state.listContent} />
</div>
</div>
</div>
);
}
};
class DispatcherNavbar extends React.Component {
constructor(props) {
super(props);
this.state = {
body: 'dispatch-map'
};
}
filter(data) {
console.log('Navbar Filter', data);
this.props.updateFilter(data);
}
driver(){
// console.log('driver', this.state);
if(this.props.body != this.state.body) {
this.setState({
body: this.props.body
});
}
if(this.state.body == 'dispatch-map') {
this.props.updateBody('driver-list');
this.setState({
body: 'driver-list'
});
}else if(this.state.body == 'dispatch-create'){
this.props.updateBody('driver-list');
this.setState({
body: 'driver-list'
});
} else {
this.props.updateBody('dispatch-map');
this.setState({
body: 'dispatch-map'
});
}
}
backaction(){
this.props.cancelback();
}
handleBodyChange() {
// console.log('handleBodyChange', this.state);
if(this.props.body != this.state.body) {
this.setState({
body: this.props.body
});
}
if(this.state.body == 'dispatch-map') {
this.props.updateBody('dispatch-create');
this.setState({
body: 'dispatch-create'
});
}else if(this.state.body == 'driver-list'){
this.props.updateBody('dispatch-create');
this.setState({
body: 'dispatch-create'
});
} else {
this.props.updateBody('dispatch-map');
this.setState({
body: 'dispatch-map'
});
}
}
render() {
return (
<div className="row bg-title">
<div className="col-lg-8 col-md-8 col-sm-8 col-xs-12">
<h4 className="page-title">Dispatcher</h4>
<button type="button"
onClick={this.filter.bind(this, 'all')}
className="btn btn-outline-warning btn-rounded w-min-sm m-l-0-75 waves-effect waves-light">
All
</button>
<a href={window.vx.schedule_url} className="btn btn-outline-warning btn-rounded w-min-sm m-l-0-75 waves-effect waves-light">Scheduled</a>
<button type="button"
onClick={this.handleBodyChange.bind(this)}
className="btn btn-outline-warning btn-rounded w-min-sm m-l-0-75 waves-effect waves-light">
ADD
</button>
<button type="button"
onClick={this.driver.bind(this)}
className="btn btn-outline-warning btn-rounded w-min-sm m-l-0-75 waves-effect waves-light">
Driver List
</button>
</div>
</div>
);
}
}
class DispatcherList extends React.Component {
constructor(props) {
super(props);
this.state = {
data: {
data: []
}
};
}
componentDidMount() {
// Mount Global Map
window.worldMapInitialize();
// Refresh trip details
window.vx.TripTimer = setInterval(
() => this.getTripsUpdate(),
1000
);
}
componentWillUnmount() {
clearInterval(window.vx.TripTimer);
}
getTripsUpdate() {
$.get('dispatcher/trips', function(result) {
//console.log('Trips', result.hasOwnProperty('data'));
if(result.hasOwnProperty('data')) {
this.setState({
data: result
});
} else {
// Might wanna show an empty list when this happens
this.setState({
data: {
data: []
}
});
}
}.bind(this));
}
handleClick(trip) {
this.props.clicked(trip);
}
render() {
// console.log(this.state.data);
return (
<div className="card">
<div className="card-header text-uppercase"><b>List</b></div>
<DispatcherListItem data={this.state.data.data} clicked={this.handleClick.bind(this)} />
</div>
);
}
}
class DispatcherListItem extends React.Component {
handleClick(trip) {
this.props.clicked(trip)
}
render() {
var listItem = function(trip) {
return (
<div className="il-item" key={trip.id} onClick={this.handleClick.bind(this, trip)}>
<a className="text-black" href="#">
<div className="media">
<div className="media-body">
<p className="mb-0-5">{trip.user == null ? 'Not Found' : trip.user.first_name} {trip.user == null ? 'Not Found' : trip.user.last_name}
{trip.status == 'COMPLETED' ?
<span className="label label-table label-success pull-right"> {trip.status} </span>
: trip.status == 'CANCELLED' ?
<span className="label label-table label-danger pull-right"> {trip.status} </span>
: trip.status == 'SEARCHING' ?
<span className="label label-table label-warning pull-right"> {trip.status} </span>
: trip.status == 'SCHEDULED' ?
<span className="label label-table label-primary pull-right"> {trip.status} </span>
:
<span className="label label-table label-info pull-right"> {trip.status} </span>
}
</p>
<h6 className="media-heading">From: {trip.s_address}</h6>
<h6 className="media-heading">To: {trip.d_address ? trip.d_address : "Not Selected"}</h6>
<h6 className="media-heading">Payment: {trip.payment_mode}</h6>
<progress className="progress progress-success progress-sm" max="100"></progress>
{trip.status == 'SCHEDULED' ?
<span className="text-muted">Scheduled at: {trip.schedule_at} <br/></span>
: '' }
<span className="text-muted">{trip.current_provider_id == 0 ? "Manual Assignment" : "Auto Search"} : {trip.created_at}</span>
</div>
</div>
</a>
</div>
);
}.bind(this);
return (
<div className="items-list">
{this.props.data.map(listItem)}
</div>
);
}
}
class DispatcherRequest extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [],
fields: {},
errors: {},
value: '1',
showStore: false
};
this.Changetrip = this.Changetrip.bind(this);
this.handlePhoneKeyUp = this.keyUpHandler.bind(this, 'Phone');
this.handleEmailKeyUp = this.keyUpHandler.bind(this, 'Email');
}
componentDidMount() {
// Auto Assign Switch
new Switchery(document.getElementById('provider_auto_assign'));
// Schedule Time Datepicker
$('#schedule_time').datetimepicker({
minDate: window.vx.minDate,
maxDate: window.vx.maxDate,
});
// Get Service Type List
$.get('/admin/service', function(result) {
this.setState({
data: result
});
}.bind(this));
// Mount Ride Create Map
window.createRideInitialize();
function stopRKey(evt) {
var evt = (evt) ? evt : ((event) ? event : null);
var node = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
if ((evt.keyCode == 13) && (node.type=="text")) {return false;}
}
document.onkeypress = stopRKey;
}
handleValidation(){
let fields = this.state.fields;
let errors = {};
let formIsValid = true;
/*//Name
if(!fields["fname"]){
formIsValid = false;
errors["fname"] = "Cannot be empty";
}
if(!fields["lname"]){
formIsValid = false;
errors["lname"] = "Cannot be empty";
}
if(!fields["phone"]){
formIsValid = false;
errors["phone"] = "Cannot be empty";
}*/
if(!fields["pickup"]){
formIsValid = false;
errors["pickup"] = "Cannot be empty";
}
if(!fields["drop"]){
formIsValid = false;
errors["drop"] = "Cannot be empty";
}
/*if(typeof fields["fname"] !== "undefined"){
if(!fields["fname"].match(/^[a-zA-Z]+$/)){
formIsValid = false;
errors["fname"] = "Only letters";
}
}
if(typeof fields["lname"] !== "undefined"){
if(!fields["lname"].match(/^[a-zA-Z]+$/)){
formIsValid = false;
errors["lname"] = "Only letters";
}
}
if(typeof fields["phone"] !== "undefined"){
if(!fields["phone"].match(/^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$/)){
formIsValid = false;
errors["phone"] = "Enter valid number";
}
}*/
//Email
/*if(!fields["email"]){
formIsValid = false;
errors["email"] = "Cannot be empty";
}
if(typeof fields["email"] !== "undefined"){
let lastAtPos = fields["email"].lastIndexOf('@');
let lastDotPos = fields["email"].lastIndexOf('.');
if (!(lastAtPos < lastDotPos && lastAtPos > 0 && fields["email"].indexOf('@@') == -1 && lastDotPos > 2 && (fields["email"].length - lastDotPos) > 2)) {
formIsValid = false;
errors["email"] = "Email is not valid";
}
}*/
this.setState({errors: errors});
return formIsValid;
}
createRide(event) {
{/* console.log(event); */}
event.preventDefault();
event.stopPropagation();
var require = 0;
if($('#first_name').val() == ''){
$('.first_name').show();
require = 1;
}else{
$('.first_name').hide();
}
if($('#last_name').val() == ''){
$('.last_name').show();
require = 1;
}else{
$('.last_name').hide();
}
if($('#email').val() == ''){
$('.email').show();
require = 1;
}else{
$('.email').hide();
}
if($('#mobile').val() == ''){
$('.mobile').show();
require = 1;
}else{
$('.mobile').hide();
}
if(require == 1){
return false;
}
console.log('Hello', $("#form-create-ride").serialize());
if(this.handleValidation()){
$.ajax({
url: '/admin/dispatcher',
dataType: 'json',
headers: {'X-CSRF-TOKEN': window.Laravel.csrfToken },
type: 'POST',
data: $("#form-create-ride").serialize(),
success: function(data) {
{/*console.log('Accept', data); */}
this.props.completed(data);
}.bind(this)
});
}
}
handleChange(field, e){
let fields = this.state.fields;
fields[field] = e.target.value;
this.setState({fields});
}
Changetrip(event) {
this.setState({value: event.target.value});
let val = event.target.value;
if(val == 2){
this.setState({ showStore: true });
}else{
this.setState({ showStore: false });
}
}
keyUpHandler(refName, e) {
console.log(refName);
let ref = refName;
if(ref == 'Phone'){
$( "#mobile" ).autocomplete({
source : '/admin/dispatcher/users-phone',
minlenght:3,
autoFill:true,
select:function(e,ui){
$('#mobile').val(ui.item.value);
$('#email').val(ui.item.email);
$('#first_name').val(ui.item.first_name);
$('#last_name').val(ui.item.last_name);
}
});
}
if(ref == 'Email'){
$( "#email" ).autocomplete({
source : '/admin/dispatcher/users-email',
minlenght:3,
autoFill:true,
select:function(e,ui){
$('#email').val(ui.item.value);
$('#mobile').val(ui.item.phone);
$('#first_name').val(ui.item.first_name);
$('#last_name').val(ui.item.last_name);
}
});
}
// prints either LoginInput or PwdInput
}
cancelCreate() {
this.props.cancel(true);
}
render() {
return (
<div className="card card-block" id="create-ride">
<h3 className="card-title text-uppercase">Ride Details</h3>
<form id="form-create-ride" onSubmit={this.createRide.bind(this)} method="POST">
<div className="row">
<div className="col-xs-6">
<div className="form-group">
<label htmlFor="first_name">First Name</label>
<input type="text" className="form-control" name="first_name" id="first_name" placeholder="First Name" onChange={this.handleChange.bind(this, "fname")} />
<p id="emailerror" className="first_name" style={{display: 'none'}}>First name required</p>
</div>
</div>
<div className="col-xs-6">
<div className="form-group">
<label htmlFor="last_name">Last Name</label>
<input type="text" className="form-control" name="last_name" id="last_name" placeholder="Last Name" onChange={this.handleChange.bind(this, "lname")}/>
<p id="emailerror" className="last_name" style={{display: 'none'}}>Last name required</p>
</div>
</div>
<div className="col-xs-6">
<div className="form-group">
<label htmlFor="email">Email</label>
<input type="text" className="form-control" name="email" id="email" placeholder="Email" onKeyUp={this.handleEmailKeyUp} onChange={this.handleChange.bind(this, "email")} ref="Email"/>
<p id="emailerror" className="email" style={{display: 'none'}}>Email id is required</p>
</div>
</div>
<div className="col-xs-6">
<div className="form-group">
<label htmlFor="mobile">Phone</label>
<input type="number" className="form-control" name="mobile" id="mobile" placeholder="Phone" onKeyUp={this.handlePhoneKeyUp} onChange={this.handleChange.bind(this, "phone")} ref="Phone"/>
<p id="emailerror" className="mobile" style={{display: 'none'}}>Mobile number is required</p>
</div>
</div>
<div className="col-xs-12">
<div className="form-group">
<label htmlFor="s_address">Pickup Address</label>
<input type="text"
name="s_address"
className="form-control"
id="s_address"
placeholder="Pickup Address"
onChange={this.handleChange.bind(this, "pickup")} ></input>
<p id="emailerror">{this.state.errors["pickup"]}</p>
<input type="hidden" name="s_latitude" id="s_latitude"></input>
<input type="hidden" name="s_longitude" id="s_longitude"></input>
</div>
<div className="form-group">
<label htmlFor="d_address">Dropoff Address</label>
<input type="text"
name="d_address"
className="form-control"
id="d_address"
placeholder="Dropoff Address"
onChange={this.handleChange.bind(this, "drop")} ></input>
<p id="emailerror">{this.state.errors["drop"]}</p>
<input type="hidden" name="d_latitude" id="d_latitude"></input>
<input type="hidden" name="d_longitude" id="d_longitude"></input>
<input type="hidden" name="distance" id="distance"></input>
</div>
<div className="form-group">
<label htmlFor="trip_types">Ride Type</label>
<select id="trip_types" name="trip_types" className="form-control" value={this.state.value} onChange={this.Changetrip}>
<option value="1">Ride Now</option>
<option value="2">Scheduled Ride</option>
</select>
</div>
<div className="form-group" id="scheduleblock" style={{display: this.state.showStore ? 'block' : 'none' }}>
<label htmlFor="schedule_time">Schedule Time</label>
<input type="text" className="form-control" name="schedule_time" id="schedule_time" placeholder="Date"/>
</div>
<div className="form-group">
<label htmlFor="service_types">Service Type</label>
<ServiceTypes data={this.state.data} />
</div>
<div className="form-group">
<label htmlFor="provider_auto_assign">Auto Assign Provider</label>
<br />
<input type="checkbox" id="provider_auto_assign" name="provider_auto_assign" className="js-switch" data-color="#f59345" defaultChecked />
</div>
</div>
</div>
<div className="row">
<div className="col-xs-6">
<button type="button" className="btn btn-lg btn-danger btn-block waves-effect waves-light" onClick={this.cancelCreate.bind(this)}>
CANCEL
</button>
</div>
<div className="col-xs-6">
<button className="btn btn-lg btn-success btn-block waves-effect waves-light">
SUBMIT
</button>
</div>
</div>
</form>
</div>
);
}
};
class DispatcherAssignList extends React.Component {
constructor(props) {
super(props);
this.state = {
data: {
data: []
}
};
}
componentDidMount() {
$.get('/admin/dispatcher/providers', {
latitude: this.props.trip.s_latitude,
longitude: this.props.trip.s_longitude
}, function(result) {
//console.log('Providers', result);
if(result.hasOwnProperty('data')) {
this.setState({
data: result
});
window.assignProviderShow(result.data, this.props.trip);
} else {
this.setState({
data: {
data: []
}
});
window.providerMarkersClear();
}
}.bind(this));
}
componentWillUnmount() {
location.reload(true);
}
render() {
//console.log('DispatcherAssignList - render', this.state.data);
return (
<div className="card">
<div className="card-header text-uppercase"><b>Assign Provider</b></div>
<DispatcherAssignListItem data={this.state.data.data} trip={this.props.trip} />
</div>
);
}
}
class DispatcherAssignListItem extends React.Component {
handleClick(provider) {
//this.props.clicked(trip)
console.log('Provider Clicked');
window.assignProviderPopPicked(provider);
}
render() {
var listItem = function(provider) {
return (
<div className="il-item" key={provider.id} onClick={this.handleClick.bind(this, provider)}>
<a className="text-black" href="#">
<div className="media">
<div className="media-body">
<p className="mb-0-5">{provider.first_name} {provider.last_name}</p>
<h6 className="media-heading">Rating: {provider.rating}</h6>
<h6 className="media-heading">Phone: {provider.mobile}</h6>
<h6 className="media-heading">Type: {provider.service.service_type.name}</h6>
</div>
</div>
</a>
</div>
);
}.bind(this);
return (
<div className="items-list">
{this.props.data.map(listItem)}
</div>
);
}
}
class ServiceTypes extends React.Component {
render() {
console.log('ServiceTypes', this.props.data);
var mySelectOptions = function(result) {
return <ServiceTypesOption
key={result.id}
id={result.id}
name={result.name} />
};
return (
<select
name="service_type"
className="form-control">
{this.props.data.map(mySelectOptions)}
</select>
)
}
}
class ServiceTypesOption extends React.Component {
render() {
return (
<option value={this.props.id}>{this.props.name}</option>
);
}
};
class DispatcherMap extends React.Component {
render() {
return (
<div className="card my-card">
<div className="card-header text-uppercase">
<b>MAP</b>
</div>
<div className="card-body">
<div id="map" style={{ height: '720px'}}></div>
</div>
</div>
);
}
}
class DriverList extends React.Component {
constructor(props) {
super(props);
this.state = {
data:[]
};
}
componentDidMount() {
window.vx.DriverTimer = setInterval(
() => this.getDriverUpdate(),
3000
);
}
componentWillUnmount() {
clearInterval(window.vx.DriverTimer);
}
getDriverUpdate() {
$.get('/admin/driver/ajax', function(result) {
this.setState({
data: result
});
}.bind(this));
}
renderDrivers() {
return this.state.data.map(driver => {
return (
<div className="il-item2" key={driver.id}>
<div className="media">
<div className="media-body">
<p className="driverpadd">{driver.firstname} {driver.lastname} - {driver.servicename}({driver.taxinumber})
{driver.currentstatus == 'active' ?
<span className="label label-table label-success pull-right"> Free In</span>
: driver.currentstatus == 'offline' ?
<span className="label label-table label-danger pull-right"> Offline</span>
: driver.currentstatus == 'riding' ?
<span className="label label-table label-primary pull-right">Riding</span>
:
<span className="label label-table label-info pull-right"> {driver.currentstatus} </span>
}
</p>
</div>
</div>
</div>
);
})
}
render() {
return(
<div className="card">
<div className="card-header text-uppercase"><b>Driver List</b></div>
<div className="items-list">
{this.renderDrivers()}
</div>
</div>
);
}
}
ReactDOM.render(
<DispatcherPanel />,
document.getElementById('dispatcher-panel')
);