added ability for client to adjust shift hours

master
Alexander Wong 6 years ago
parent ffa46b1435
commit fb5f71a881
No known key found for this signature in database
GPG Key ID: E90E5D6448C2C663
  1. 2
      src/api/employer.api.js
  2. 25
      src/components/Shared/ShiftLabel.jsx
  3. 2
      src/components/User/Client/ClientAddShiftForm.jsx
  4. 11
      src/components/User/Client/ClientEditShiftForm.jsx
  5. 9
      src/components/User/Client/ClientShiftFormView.jsx
  6. 198
      src/components/User/Client/ClientShifts.jsx
  7. 47
      src/components/User/Provider/ProviderShift.jsx
  8. 67
      src/components/User/Provider/ProviderShifts.jsx

@ -6,7 +6,7 @@ import { put } from "./baseApi";
* @param {boolean} approved - whether or not to approve employment relationship
*/
export function updateEmployer(uuid, approved) {
return put(`/employer/${uuid}/`, { approved }).then(resp =>
return put(`/employer/${uuid}/`, { provider_approved: approved }).then(resp =>
Promise.resolve(resp)
);
}

@ -0,0 +1,25 @@
import React from "react";
import { Label } from "semantic-ui-react";
export default ({
provider_approved,
client_approved_start,
client_approved_end
}) => {
const providerApproved = !!provider_approved;
const clientApproved = !!client_approved_start && providerApproved;
const providerRejected = !provider_approved && provider_approved !== null;
const providerPending = provider_approved === null;
return (
<Label
color={providerApproved ? "green" : providerRejected ? "red" : "grey"}
tag
size="small"
>
{!clientApproved && providerApproved && "Provider Approved Shift"}
{clientApproved && "Client Approved Hours"}
{providerPending && "Provider Approval Pending"}
{providerRejected && "Provider Rejected Shift"}
</Label>
);
};

@ -82,6 +82,8 @@ class ClientAddShiftForm extends Component {
get_price_uuid: priceUUID,
set_start: dynamicStartTime.format(),
set_end: dynamicEndTime.format(),
approved_start: null,
approved_end: null,
description: note ? note : undefined
});
}

@ -87,6 +87,7 @@ class ClientEditShiftForm extends Component {
event.preventDefault();
// change this into interable cshift post request bodies
const {
cShiftRequestSuccess,
cShiftUUID,
priceUUID,
startTime,
@ -94,6 +95,8 @@ class ClientEditShiftForm extends Component {
note,
shiftDates
} = this.props;
const isProviderCheckedIn = !!cShiftRequestSuccess.actual_start;
const postRequestBodies = [];
for (let shiftDateString in shiftDates) {
const dynamicStartTime = utc(startTime);
@ -107,8 +110,10 @@ class ClientEditShiftForm extends Component {
dynamicEndTime.add(duration, "minutes");
postRequestBodies.push({
get_price_uuid: priceUUID,
set_start: dynamicStartTime.format(),
set_end: dynamicEndTime.format(),
set_start: isProviderCheckedIn ? null : dynamicStartTime.format(),
set_end: isProviderCheckedIn ? null : dynamicEndTime.format(),
approved_start: isProviderCheckedIn ? dynamicStartTime.format() : null,
approved_end: isProviderCheckedIn ? dynamicEndTime.format() : null,
description: note ? note : undefined
});
}
@ -131,6 +136,7 @@ class ClientEditShiftForm extends Component {
shiftDates,
cShiftUUID
} = this.props;
const isProviderCheckedIn = !!cShiftRequestSuccess.actual_start;
if (!selfUser.client) {
return <Redirect to="/" />;
@ -206,6 +212,7 @@ class ClientEditShiftForm extends Component {
handleSelectDate={this.handleSelectDate}
onSubmitShifts={this.onSubmitShifts}
isEditing={true}
isProviderCheckedIn={isProviderCheckedIn}
/>
);
}

@ -49,12 +49,14 @@ export const ClientShiftFormView = ({
changeShiftNote,
handleSelectDate,
onSubmitShifts,
isEditing = false
isEditing = false,
isProviderCheckedIn = false
}) => (
<Container>
<Header>
{!isEditing && "Schedule Shifts"}
{isEditing && "Edit Shift"}
{isEditing && !isProviderCheckedIn && "Edit Shift"}
{isEditing && isProviderCheckedIn && "Adjust and Approve Hours"}
</Header>
<Form
loading={isSendingCShiftRequest}
@ -151,7 +153,8 @@ export const ClientShiftFormView = ({
</Message>
<Form.Button>
{!isEditing && "Schedule Shifts"}
{isEditing && "Edit Shift"}
{isEditing && !isProviderCheckedIn && "Edit Shift"}
{isEditing && isProviderCheckedIn && "Adjust and Approve Hours"}
</Form.Button>
</Form>
</Container>

@ -1,5 +1,5 @@
import { utc, ISO_8601, duration } from "moment";
import React, { Component } from "react";
import React, { Component, Fragment } from "react";
import { connect } from "react-redux";
import { Redirect, Link } from "react-router-dom";
import {
@ -25,9 +25,11 @@ import {
} from "../../../actions/cShift/reducer.actions";
import {
getCShiftsRequest,
deleteCShiftRequest
deleteCShiftRequest,
editCShiftRequest
} from "../../../actions/cShift/saga.actions";
import { getEmployeeFromPrice, getPriceFromPrice } from "./ClientShiftShared";
import ShiftLabel from "../../Shared/ShiftLabel";
class ClientShifts extends Component {
constructor(props) {
@ -41,7 +43,7 @@ class ClientShifts extends Component {
this.props.dispatch(
getCShiftsRequest({
page: this.props.page,
approved: this.props.approvalFilter,
provider_approved: this.props.approvalFilter,
completed: this.props.completedFilter,
manage: this.props.providerFilter,
work_type: this.props.workTypeFilter,
@ -54,7 +56,7 @@ class ClientShifts extends Component {
this.props.dispatch(
getCShiftsRequest({
page: activePage,
approved: this.props.approvalFilter,
provider_approved: this.props.approvalFilter,
manage: this.props.providerFilter,
work_type: this.props.workTypeFilter,
page_size: this.state.pageSize
@ -67,7 +69,7 @@ class ClientShifts extends Component {
this.props.dispatch(
getCShiftsRequest({
page: 1,
approved: value,
provider_approved: value,
completed: this.props.completedFilter,
manage: this.props.providerFilter,
work_type: this.props.workTypeFilter,
@ -82,7 +84,7 @@ class ClientShifts extends Component {
this.props.dispatch(
getCShiftsRequest({
page: 1,
approved: this.props.approvalFilter,
provider_approved: this.props.approvalFilter,
completed: value,
manage: this.props.providerFilter,
work_type: this.props.workTypeFilter,
@ -97,7 +99,7 @@ class ClientShifts extends Component {
this.props.dispatch(
getCShiftsRequest({
page: 1,
approved: this.props.approvalFilter,
provider_approved: this.props.approvalFilter,
completed: this.props.completedFilter,
manage: value,
work_type: this.props.workTypeFilter,
@ -112,7 +114,7 @@ class ClientShifts extends Component {
this.props.dispatch(
getCShiftsRequest({
page: 1,
approved: this.props.approvalFilter,
provider_approved: this.props.approvalFilter,
completed: this.props.completedFilter,
manage: this.props.manageFilter,
work_type: value,
@ -127,6 +129,34 @@ class ClientShifts extends Component {
this.props.dispatch(deleteCShiftRequest(uuid));
};
approveHoursCShift = cshift => {
const {
set_start: approved_start,
set_end: approved_end,
price: get_price_uuid
} = cshift;
this.props.dispatch(
editCShiftRequest({
uuid: cshift.uuid,
get_price_uuid,
approved_start,
approved_end,
set_start: null,
set_end: null
})
);
this.props.dispatch(
getCShiftsRequest({
page: this.props.page,
provider_approved: this.props.approvalFilter,
completed: this.props.completedFilter,
manage: this.props.providerFilter,
work_type: this.props.workTypeFilter,
page_size: this.state.pageSize
})
);
};
render() {
const {
isSendingCShiftRequest,
@ -157,6 +187,7 @@ class ClientShifts extends Component {
handleChangeProviderFilter={this.handleChangeProviderFilter}
handleChangeWorkTypeFilter={this.handleChangeWorkTypeFilter}
deleteCShift={this.deleteCShift}
approveHoursCShift={this.approveHoursCShift}
/>
);
} else {
@ -184,7 +215,8 @@ const ClientShiftsView = ({
handleChangeCompletedFilter,
handleChangeProviderFilter,
handleChangeWorkTypeFilter,
deleteCShift
deleteCShift,
approveHoursCShift
}) => {
const { count = 0, results = [] } = cShiftRequestSuccess;
const approvedOptions = [
@ -240,7 +272,7 @@ const ClientShiftsView = ({
Schedule Shift
</Button>
<Segment>
{"Filter by Approval "}
{"Filter by Provider Approval "}
<Dropdown
inline
placeholder={approvalFilter === null ? `All` : `Pending`}
@ -302,9 +334,7 @@ const ClientShiftsView = ({
"minutes"
).humanize()}`;
}
const approved = !!result.approved;
const rejected = !result.approved && result.approved !== null;
const pending = result.approved === null;
return (
<Item key={result.uuid}>
<Item.Content>
@ -320,18 +350,14 @@ const ClientShiftsView = ({
{workType.label}
</Item.Header>
<Item.Extra>
<Label
color={approved ? "green" : rejected ? "red" : "grey"}
tag
size="small"
>
{approved && "Approved"}
{pending && "Approval Pending"}
{rejected && "Rejected"}
</Label>
<ShiftLabel
provider_approved={result.provider_approved}
client_approved_start={result.approved_start}
client_approved_end={result.approved_end}
/>
</Item.Extra>
<Item.Meta>
{"At " +
{"Scheduled for " +
utc(result.set_start, ISO_8601)
.local(false)
.format(OLD_PEOPLE_TIME_FORMAT)}
@ -348,14 +374,6 @@ const ClientShiftsView = ({
</Item.Content>
{!checkedIn && (
<Item.Extra>
<Button
primary
floated="right"
as={Link}
to={`/user/profile/client/edit-shift/${result.uuid}`}
>
Edit
</Button>
<Popup
content={
<div>
@ -378,39 +396,109 @@ const ClientShiftsView = ({
on="click"
position="top right"
/>
<Button
primary
floated="right"
as={Link}
to={`/user/profile/client/edit-shift/${result.uuid}`}
>
Edit
</Button>
</Item.Extra>
)}
{checkedIn && (
<Item.Content>
<Item.Description>
{result.description && (
<Message>{result.description}</Message>
)}
<strong>Provider</strong>
<List bulleted>
<List.Item>
{"Checked in at " +
checkedIn
.local(false)
.format(OLD_PEOPLE_TIME_FORMAT)}
</List.Item>
{checkedOut && (
<Fragment>
<Item.Content>
<Item.Description>
{result.description && (
<Message>{result.description}</Message>
)}
{result.approved_start && (
<Fragment>
<strong>Client</strong>
<List bulleted>
<List.Item>
{`Approved time start ${utc(
result.approved_start
)
.local(false)
.format(OLD_PEOPLE_TIME_FORMAT)}`}
</List.Item>
<List.Item>{`Approved time end ${utc(
result.approved_end
)
.local(false)
.format(OLD_PEOPLE_TIME_FORMAT)}`}</List.Item>
</List>
</Fragment>
)}
<strong>Provider</strong>
<List bulleted>
<List.Item>
{"Checked out at " +
checkedOut
{"Checked in at " +
checkedIn
.local(false)
.format(OLD_PEOPLE_TIME_FORMAT)}
</List.Item>
{checkedOut && (
<List.Item>
{"Checked out at " +
checkedOut
.local(false)
.format(OLD_PEOPLE_TIME_FORMAT)}
</List.Item>
)}
</List>
{result.chart && (
<Message>
<Message.Header>Chart</Message.Header>
{result.chart}
</Message>
)}
</List>
{result.chart && (
<Message>
<Message.Header>Chart</Message.Header>
{result.chart}
</Message>
</Item.Description>
</Item.Content>
<Item.Extra>
<Popup
content={
<div>
Are you sure you want to delete this shift?<br />
<Button
basic
color="red"
size="small"
onClick={() => deleteCShift(result.uuid)}
>
Confirm Deletion
</Button>
</div>
}
trigger={
<Button color="red" floated="right">
Delete
</Button>
}
on="click"
position="top right"
/>
<Button
primary
floated="right"
as={Link}
to={`/user/profile/client/edit-shift/${result.uuid}`}
>
Adjust Hours
</Button>
{!result.approved_start && (
<Button
color="green"
floated="right"
onClick={() => approveHoursCShift(result)}
>
Approve Hours
</Button>
)}
</Item.Description>
</Item.Content>
</Item.Extra>
</Fragment>
)}
</Item>
);

@ -1,5 +1,5 @@
import { utc, duration, ISO_8601 } from "moment";
import React, { Component } from "react";
import React, { Component, Fragment } from "react";
import { connect } from "react-redux";
import { Redirect } from "react-router-dom";
import {
@ -27,6 +27,7 @@ import {
getWorkTypeFromPrice,
getPriceFromPrice
} from "./ProviderShiftsShared";
import ShiftLabel from "../../Shared/ShiftLabel";
class ProviderShift extends Component {
handleChangePShiftApproval = (uuid, approved) => {
@ -34,7 +35,7 @@ class ProviderShift extends Component {
this.props.dispatch(
updatePShiftRequest({
uuid,
approved,
provider_approved: approved,
action: "",
chart: null,
single: true
@ -48,7 +49,7 @@ class ProviderShift extends Component {
this.props.dispatch(
updatePShiftRequest({
uuid: pShiftRequestSuccess.uuid,
approved: true,
provider_approved: true,
action: "checkin",
chart: null,
single: true
@ -65,7 +66,7 @@ class ProviderShift extends Component {
this.props.dispatch(
updatePShiftRequest({
uuid: pShiftRequestSuccess.uuid,
approved: true,
provider_approved: true,
action: "checkout",
chart,
single: true
@ -128,22 +129,18 @@ const ProviderShiftFormView = ({
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;
const approved = !!shift.provider_approved;
const rejected = !shift.provider_approved && shift.provider_approved !== null;
// const pending = shift.provider_approved === null;
return (
<Container>
<Header>Shift Details</Header>
<Loader active={isSendingPShiftRequest} />
<Label
color={approved ? "green" : rejected ? "red" : "grey"}
tag
size="small"
>
{approved && "Approved"}
{pending && "Approval Pending"}
{rejected && "Rejected"}
</Label>
<ShiftLabel
provider_approved={shift.provider_approved}
client_approved_start={shift.approved_start}
client_approved_end={shift.approved_end}
/>
<Label
circular
empty
@ -155,7 +152,7 @@ const ProviderShiftFormView = ({
{workType.label}
<List bulleted>
<List.Item>
{"Scheduled at " +
{"Scheduled for " +
utc(shift.set_start, ISO_8601)
.local(false)
.format(OLD_PEOPLE_TIME_FORMAT)}
@ -194,6 +191,22 @@ const ProviderShiftFormView = ({
)}
</Button.Group>
)}
{shift.approved_start && (
<Fragment>
<strong>Client</strong>
<List bulleted>
<List.Item>
{`Approved time start ${utc(shift.approved_start)
.local(false)
.format(OLD_PEOPLE_TIME_FORMAT)}`}
</List.Item>
<List.Item>{`Approved time end ${utc(shift.approved_end)
.local(false)
.format(OLD_PEOPLE_TIME_FORMAT)}`}</List.Item>
</List>
</Fragment>
)}
<strong>Provider</strong>
<List bulleted>
{!checkedIn && <List.Item>Pending Check In</List.Item>}{" "}
{checkedIn && (

@ -1,5 +1,5 @@
import { utc, ISO_8601, duration } from "moment";
import React, { Component } from "react";
import React, { Component, Fragment } from "react";
import { connect } from "react-redux";
import { Redirect, Link } from "react-router-dom";
import {
@ -11,7 +11,8 @@ import {
Segment,
Pagination,
Loader,
Label
Label,
List
} from "semantic-ui-react";
import {
getEmployerFromPrice,
@ -28,6 +29,7 @@ import {
getPShiftsRequest,
updatePShiftRequest
} from "../../../actions/pShift/saga.actions";
import ShiftLabel from "../../Shared/ShiftLabel";
class ProviderShifts extends Component {
constructor(props) {
@ -41,7 +43,7 @@ class ProviderShifts extends Component {
this.props.dispatch(
getPShiftsRequest({
page: this.props.page,
approved: this.props.approvalFilter,
provider_approved: this.props.approvalFilter,
completed: this.props.completedFilter,
manage: this.props.clientFilter,
work_type: this.props.workTypeFilter,
@ -54,7 +56,7 @@ class ProviderShifts extends Component {
this.props.dispatch(
getPShiftsRequest({
page: activePage,
approved: this.props.approvalFilter,
provider_approved: this.props.approvalFilter,
completed: this.props.completedFilter,
manage: this.props.clientFilter,
work_type: this.props.workTypeFilter,
@ -68,7 +70,7 @@ class ProviderShifts extends Component {
this.props.dispatch(
getPShiftsRequest({
page: 1,
approved: value,
provider_approved: value,
completed: this.props.completedFilter,
manage: this.props.clientFilter,
work_type: this.props.workTypeFilter,
@ -83,7 +85,7 @@ class ProviderShifts extends Component {
this.props.dispatch(
getPShiftsRequest({
page: 1,
approved: this.props.approvalFilter,
provider_approved: this.props.approvalFilter,
completed: value,
manage: this.props.clientFilter,
work_type: this.props.workTypeFilter,
@ -98,7 +100,7 @@ class ProviderShifts extends Component {
this.props.dispatch(
getPShiftsRequest({
page: 1,
approved: this.props.approvalFilter,
provider_approved: this.props.approvalFilter,
completed: this.props.completedFilter,
manage: value,
work_type: this.props.workTypeFilter,
@ -113,7 +115,7 @@ class ProviderShifts extends Component {
this.props.dispatch(
getPShiftsRequest({
page: 1,
approved: this.props.approvalFilter,
provider_approved: this.props.approvalFilter,
completed: this.props.completedFilter,
manage: this.props.clientFilter,
work_type: value,
@ -127,7 +129,12 @@ class ProviderShifts extends Component {
handleChangePShiftApproval = (uuid, approved) => {
return () => {
this.props.dispatch(
updatePShiftRequest({ uuid, approved, action: "", chart: null })
updatePShiftRequest({
uuid,
provider_approved: approved,
action: "",
chart: null
})
);
};
};
@ -244,7 +251,7 @@ const ProviderShiftsView = ({
<Header>Shifts</Header>
<Segment.Group horizontal>
<Segment>
{"Filter by Approval "}
{"Filter by Provider Approval "}
<Dropdown
inline
placeholder={approvalFilter === null ? `All` : `Pending`}
@ -306,9 +313,10 @@ const ProviderShiftsView = ({
"minutes"
).humanize()}`;
}
const approved = !!result.approved;
const rejected = !result.approved && result.approved !== null;
const pending = result.approved === null;
const approved = !!result.provider_approved;
const rejected =
!result.provider_approved && result.provider_approved !== null;
// const pending = result.provider_approved === null;
return (
<Item key={result.uuid}>
<Item.Content>
@ -324,18 +332,14 @@ const ProviderShiftsView = ({
{workType.label}
</Item.Header>
<Item.Extra>
<Label
color={approved ? "green" : rejected ? "red" : "grey"}
tag
size="small"
>
{approved && "Approved"}
{pending && "Approval Pending"}
{rejected && "Rejected"}
</Label>
<ShiftLabel
provider_approved={result.provider_approved}
client_approved_start={result.approved_start}
client_approved_end={result.approved_end}
/>
</Item.Extra>
<Item.Meta>
{"At " +
{"Scheduled for " +
utc(result.set_start, ISO_8601)
.local(false)
.format(OLD_PEOPLE_TIME_FORMAT)}
@ -363,6 +367,23 @@ const ProviderShiftsView = ({
.format(OLD_PEOPLE_TIME_FORMAT)}
</Item.Meta>
)}
{result.approved_start && (
<Fragment>
<strong>Client</strong>
<List bulleted>
<List.Item>
{`Approved time start ${utc(result.approved_start)
.local(false)
.format(OLD_PEOPLE_TIME_FORMAT)}`}
</List.Item>
<List.Item>{`Approved time end ${utc(
result.approved_end
)
.local(false)
.format(OLD_PEOPLE_TIME_FORMAT)}`}</List.Item>
</List>
</Fragment>
)}
</Item.Content>
<Item.Extra>
{!checkedIn && (

Loading…
Cancel
Save