2018-04-23 17:07:33 +00:00
|
|
|
import { utc, duration, ISO_8601 } from "moment";
|
|
|
|
import React, { Component } from "react";
|
|
|
|
import { connect } from "react-redux";
|
|
|
|
import { Redirect } from "react-router-dom";
|
|
|
|
import {
|
|
|
|
Button,
|
|
|
|
Container,
|
|
|
|
Header,
|
|
|
|
Label,
|
|
|
|
List,
|
|
|
|
Loader,
|
2018-04-23 18:19:14 +00:00
|
|
|
Message,
|
|
|
|
TextArea,
|
|
|
|
Form
|
2018-04-23 17:07:33 +00:00
|
|
|
} from "semantic-ui-react";
|
2018-04-23 18:19:14 +00:00
|
|
|
import {
|
|
|
|
setClearPShiftState,
|
|
|
|
setFormShiftChart
|
|
|
|
} from "../../../actions/pShift/reducer.actions";
|
2018-04-23 17:07:33 +00:00
|
|
|
import {
|
|
|
|
getPShiftRequest,
|
|
|
|
updatePShiftRequest
|
|
|
|
} from "../../../actions/pShift/saga.actions";
|
|
|
|
import Error from "../../Shared/Error";
|
|
|
|
import {
|
|
|
|
getEmployerFromPrice,
|
|
|
|
getWorkTypeFromPrice,
|
|
|
|
getPriceFromPrice
|
|
|
|
} from "./ProviderShiftsShared";
|
|
|
|
|
|
|
|
class ProviderShift extends Component {
|
|
|
|
handleChangePShiftApproval = (uuid, approved) => {
|
|
|
|
return () => {
|
|
|
|
this.props.dispatch(
|
|
|
|
updatePShiftRequest({
|
|
|
|
uuid,
|
|
|
|
approved,
|
|
|
|
action: "",
|
|
|
|
chart: null,
|
|
|
|
single: true
|
|
|
|
})
|
|
|
|
);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2018-04-23 18:19:14 +00:00
|
|
|
handleCheckInPShift = () => {
|
|
|
|
const { pShiftRequestSuccess } = this.props;
|
|
|
|
this.props.dispatch(
|
|
|
|
updatePShiftRequest({
|
|
|
|
uuid: pShiftRequestSuccess.uuid,
|
|
|
|
approved: true,
|
|
|
|
action: "checkin",
|
|
|
|
chart: null,
|
|
|
|
single: true
|
|
|
|
})
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
handleChangeChart = event => {
|
|
|
|
this.props.dispatch(setFormShiftChart(event.target.value));
|
|
|
|
};
|
|
|
|
|
|
|
|
handleCheckOutPShift = () => {
|
|
|
|
const { pShiftRequestSuccess, chart } = this.props;
|
|
|
|
this.props.dispatch(
|
|
|
|
updatePShiftRequest({
|
|
|
|
uuid: pShiftRequestSuccess.uuid,
|
|
|
|
approved: true,
|
|
|
|
action: "checkout",
|
|
|
|
chart,
|
|
|
|
single: true
|
|
|
|
})
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2018-04-23 17:07:33 +00:00
|
|
|
render() {
|
|
|
|
const {
|
|
|
|
isSendingPShiftRequest,
|
|
|
|
pShiftRequestError,
|
|
|
|
pShiftRequestSuccess,
|
2018-04-23 18:19:14 +00:00
|
|
|
selfUser,
|
|
|
|
chart
|
2018-04-23 17:07:33 +00:00
|
|
|
} = this.props;
|
|
|
|
|
|
|
|
if (!selfUser.provider) {
|
|
|
|
return <Redirect to="/" />;
|
|
|
|
}
|
|
|
|
return (
|
|
|
|
<ProviderShiftFormView
|
|
|
|
isSendingPShiftRequest={isSendingPShiftRequest}
|
|
|
|
pShiftRequestError={pShiftRequestError}
|
|
|
|
shift={pShiftRequestSuccess}
|
2018-04-23 18:19:14 +00:00
|
|
|
chart={chart}
|
2018-04-23 17:07:33 +00:00
|
|
|
user={selfUser}
|
|
|
|
handleChangePShiftApproval={this.handleChangePShiftApproval}
|
2018-04-23 18:19:14 +00:00
|
|
|
handleChangeChart={this.handleChangeChart}
|
|
|
|
handleCheckInPShift={this.handleCheckInPShift}
|
|
|
|
handleCheckOutPShift={this.handleCheckOutPShift}
|
2018-04-23 17:07:33 +00:00
|
|
|
/>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const ProviderShiftFormView = ({
|
|
|
|
isSendingPShiftRequest,
|
|
|
|
pShiftRequestError,
|
|
|
|
shift,
|
2018-04-23 18:19:14 +00:00
|
|
|
chart,
|
2018-04-23 17:07:33 +00:00
|
|
|
user,
|
2018-04-23 18:19:14 +00:00
|
|
|
handleChangeChart,
|
|
|
|
handleChangePShiftApproval,
|
|
|
|
handleCheckInPShift,
|
|
|
|
handleCheckOutPShift
|
2018-04-23 17:07:33 +00:00
|
|
|
}) => {
|
|
|
|
const employer = getEmployerFromPrice(shift.price, user) || {};
|
|
|
|
const client = employer.client || {};
|
|
|
|
const workType = getWorkTypeFromPrice(shift.price, user) || {};
|
|
|
|
const price = getPriceFromPrice(shift.price, user) || {};
|
2018-04-23 18:19:14 +00:00
|
|
|
const checkedIn = !!shift.actual_start && utc(shift.actual_start, ISO_8601);
|
|
|
|
const checkedOut = !!shift.actual_end && utc(shift.actual_end, ISO_8601);
|
2018-04-23 17:07:33 +00:00
|
|
|
const min = duration(
|
|
|
|
utc(shift.set_end, ISO_8601) - utc(shift.set_start, ISO_8601),
|
|
|
|
"milliseconds"
|
|
|
|
).as("minutes");
|
|
|
|
let displayDuration = duration(min, "minutes").humanize();
|
|
|
|
if (min % 60) {
|
|
|
|
displayDuration = duration(Math.floor(min / 60), "hours").humanize();
|
|
|
|
displayDuration += ` and ${duration(min % 60, "minutes").humanize()}`;
|
|
|
|
}
|
|
|
|
const approved = !!shift.approved;
|
|
|
|
const rejected = !shift.approved && shift.approved !== null;
|
|
|
|
const pending = shift.approved === null;
|
|
|
|
return (
|
|
|
|
<Container>
|
|
|
|
<Header>Shift Details</Header>
|
|
|
|
<Loader active={isSendingPShiftRequest} />
|
2018-04-23 18:19:14 +00:00
|
|
|
<Label
|
|
|
|
color={approved ? "green" : rejected ? "red" : "grey"}
|
|
|
|
tag
|
|
|
|
size="small"
|
|
|
|
>
|
2018-04-23 17:07:33 +00:00
|
|
|
{approved && "Approved"}
|
|
|
|
{pending && "Approval Pending"}
|
|
|
|
{rejected && "Rejected"}
|
|
|
|
</Label>
|
|
|
|
<Label
|
|
|
|
circular
|
|
|
|
empty
|
|
|
|
style={{
|
|
|
|
backgroundColor: workType.color,
|
|
|
|
borderColor: workType.color
|
|
|
|
}}
|
|
|
|
/>{" "}
|
|
|
|
{workType.label}
|
|
|
|
<List bulleted>
|
|
|
|
<List.Item>
|
|
|
|
{"Scheduled at " +
|
|
|
|
utc(shift.set_start, ISO_8601)
|
|
|
|
.local(false)
|
|
|
|
.format("dddd, MMMM Do YYYY, h:mm a Z")}
|
|
|
|
</List.Item>
|
|
|
|
<List.Item>{displayDuration}</List.Item>
|
|
|
|
<List.Item>{`Rate $${price.amount}/hour`}</List.Item>
|
|
|
|
<List.Item>
|
|
|
|
<strong>Employer/Client:</strong>{" "}
|
|
|
|
{`${client.first_name} ${client.last_name}`.trim() || "No Name!"}{" "}
|
|
|
|
<a href={"mailto:" + client.email}>{client.email}</a>
|
|
|
|
</List.Item>
|
|
|
|
</List>
|
|
|
|
{shift.description && (
|
|
|
|
<Message>
|
|
|
|
<Message.Header>Description</Message.Header>
|
|
|
|
<p>{shift.description}</p>
|
|
|
|
</Message>
|
|
|
|
)}
|
2018-04-23 18:19:14 +00:00
|
|
|
{!checkedIn && (
|
|
|
|
<Button.Group>
|
|
|
|
{!approved && (
|
|
|
|
<Button
|
|
|
|
color="green"
|
|
|
|
onClick={handleChangePShiftApproval(shift.uuid, true)}
|
|
|
|
>
|
|
|
|
Approve
|
|
|
|
</Button>
|
|
|
|
)}
|
|
|
|
{!rejected && (
|
|
|
|
<Button
|
|
|
|
color="red"
|
|
|
|
onClick={handleChangePShiftApproval(shift.uuid, false)}
|
|
|
|
>
|
|
|
|
Reject
|
|
|
|
</Button>
|
|
|
|
)}
|
|
|
|
</Button.Group>
|
|
|
|
)}
|
|
|
|
<List bulleted>
|
|
|
|
{!checkedIn && <List.Item>Pending Check In</List.Item>}{" "}
|
|
|
|
{checkedIn && (
|
|
|
|
<List.Item>
|
|
|
|
<strong>Checked In At:</strong>{" "}
|
|
|
|
{checkedIn.local(false).format("dddd, MMMM Do YYYY, h:mm a Z")}
|
|
|
|
</List.Item>
|
|
|
|
)}
|
|
|
|
{checkedOut && (
|
|
|
|
<List.Item>
|
|
|
|
<strong>Checked Out At:</strong>{" "}
|
|
|
|
{checkedOut.local(false).format("dddd, MMMM Do YYYY, h:mm a Z")}
|
|
|
|
</List.Item>
|
2018-04-23 17:07:33 +00:00
|
|
|
)}
|
2018-04-23 18:19:14 +00:00
|
|
|
</List>
|
|
|
|
{shift.chart && (
|
|
|
|
<Message>
|
|
|
|
<Message.Header>Chart</Message.Header>
|
|
|
|
{shift.chart}
|
|
|
|
</Message>
|
|
|
|
)}
|
|
|
|
{!checkedIn && <Button onClick={handleCheckInPShift}>Check In</Button>}
|
|
|
|
{checkedIn &&
|
|
|
|
!checkedOut && (
|
|
|
|
<Form onSubmit={handleCheckOutPShift}>
|
|
|
|
<label>Chart</label>
|
|
|
|
<TextArea
|
|
|
|
value={chart}
|
|
|
|
onChange={handleChangeChart}
|
|
|
|
placeholder="Chart"
|
|
|
|
/>
|
|
|
|
<Button>Check Out</Button>
|
|
|
|
</Form>
|
2018-04-23 17:07:33 +00:00
|
|
|
)}
|
2018-04-23 18:19:14 +00:00
|
|
|
<Error error={pShiftRequestError} />
|
2018-04-23 17:07:33 +00:00
|
|
|
</Container>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
function mapStateToProps(state) {
|
|
|
|
return { ...state.pShift, selfUser: state.user.selfUser };
|
|
|
|
}
|
|
|
|
|
|
|
|
class ProviderShiftWrapper extends Component {
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
this.props.dispatch(setClearPShiftState());
|
|
|
|
this.props.dispatch(
|
|
|
|
getPShiftRequest({ uuid: this.props.match.params.shiftUUID })
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
|
|
|
const { pShiftRequestSuccess, pShiftRequestError } = this.props;
|
|
|
|
if (pShiftRequestSuccess.uuid) {
|
|
|
|
return <ProviderShift {...this.props} />;
|
|
|
|
} else if (!pShiftRequestError) {
|
|
|
|
return <Loader active />;
|
|
|
|
} else {
|
|
|
|
return <Error error={pShiftRequestError} />;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default connect(mapStateToProps)(ProviderShiftWrapper);
|