working edit cshift functionality
This commit is contained in:
parent
0950f264e8
commit
4f548d529f
|
@ -10,6 +10,7 @@ import {
|
|||
SET_FORM_SHIFT_DURATION,
|
||||
SET_FORM_SHIFT_NOTE,
|
||||
SET_FORM_SHIFT_DATES,
|
||||
SET_CSHIFT_UUID,
|
||||
SET_CLEAR_CSHIFT_STATE
|
||||
} from "../../constants/cShift.constants";
|
||||
import { parseError } from "../common.actions";
|
||||
|
@ -43,7 +44,7 @@ export function setCShiftRequestErrors(exceptions) {
|
|||
return {
|
||||
type: SET_CSHIFT_REQUEST_ERRORS,
|
||||
data: errors
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function clearCShiftRequestError() {
|
||||
|
@ -107,6 +108,13 @@ export function setFormShiftDates(dates) {
|
|||
};
|
||||
}
|
||||
|
||||
export function setCShiftUUID(uuid) {
|
||||
return {
|
||||
type: SET_CSHIFT_UUID,
|
||||
data: uuid
|
||||
};
|
||||
}
|
||||
|
||||
export function setClearCShiftState() {
|
||||
return {
|
||||
type: SET_CLEAR_CSHIFT_STATE
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import {
|
||||
CREATE_MULTIPLE_CSHIFT_REQUEST,
|
||||
GET_CSHIFTS_REQUEST
|
||||
GET_CSHIFTS_REQUEST,
|
||||
GET_CSHIFT_REQUEST,
|
||||
EDIT_CSHIFT_REQUEST
|
||||
} from "../../constants/cShift.constants";
|
||||
|
||||
/**
|
||||
|
@ -20,3 +22,17 @@ export function getCShiftsRequest(params) {
|
|||
data: params
|
||||
};
|
||||
}
|
||||
|
||||
export function getCShiftRequest(payload) {
|
||||
return {
|
||||
type: GET_CSHIFT_REQUEST,
|
||||
data: payload
|
||||
};
|
||||
}
|
||||
|
||||
export function editCShiftRequest(payload) {
|
||||
return {
|
||||
type: EDIT_CSHIFT_REQUEST,
|
||||
data: payload
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { get, post } from "./baseApi";
|
||||
import { get, put, post } from "./baseApi";
|
||||
|
||||
export function createCShifts(postBodies) {
|
||||
return Promise.all(
|
||||
|
@ -15,3 +15,11 @@ export function createCShifts(postBodies) {
|
|||
export function getCShifts(params) {
|
||||
return get("/cshift/", params).then(resp => Promise.resolve(resp));
|
||||
}
|
||||
|
||||
export function getCShift(uuid, params) {
|
||||
return get(`/cshift/${uuid}/`, params).then(resp => Promise.resolve(resp));
|
||||
}
|
||||
|
||||
export function editCShift(uuid, payload) {
|
||||
return put(`/cshift/${uuid}/`, payload).then(resp => Promise.resolve(resp));
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import UpdatePriceForm from "./User/Client/UpdatePriceForm";
|
|||
import ClientAddProviderForm from "./User/Client/ClientAddProviderForm";
|
||||
import ClientShifts from "./User/Client/ClientShifts";
|
||||
import ClientAddShiftForm from "./User/Client/ClientAddShiftForm";
|
||||
import ClientEditShiftForm from "./User/Client/ClientEditShiftForm";
|
||||
import ProviderClients from "./User/Provider/ProviderClients";
|
||||
import CompleteRegistration from "./User/CompleteRegistration";
|
||||
import EditProfile from "./User/EditProfile";
|
||||
|
@ -92,6 +93,10 @@ class App extends Component {
|
|||
path="/user/profile/client/add-shift"
|
||||
component={ClientAddShiftForm}
|
||||
/>
|
||||
<PrivateRoute
|
||||
path="/user/profile/client/edit-shift/:shiftUUID"
|
||||
component={ClientEditShiftForm}
|
||||
/>
|
||||
<PrivateRoute
|
||||
path="/user/profile/provider/clients"
|
||||
component={ProviderClients}
|
||||
|
|
|
@ -1,17 +1,8 @@
|
|||
import { duration, utc } from "moment";
|
||||
import { utc } from "moment";
|
||||
import React, { Component } from "react";
|
||||
import DatePicker from "react-datepicker";
|
||||
import { connect } from "react-redux";
|
||||
import { Redirect } from "react-router-dom";
|
||||
import {
|
||||
Container,
|
||||
Dropdown,
|
||||
Form,
|
||||
Header,
|
||||
Label,
|
||||
Message,
|
||||
TextArea
|
||||
} from "semantic-ui-react";
|
||||
import { Header, Label } from "semantic-ui-react";
|
||||
|
||||
import {
|
||||
setFormEmployeeUUID,
|
||||
|
@ -23,24 +14,7 @@ import {
|
|||
setFormShiftDates
|
||||
} from "../../../actions/cShift/reducer.actions";
|
||||
import { createMultipleCShiftRequest } from "../../../actions/cShift/saga.actions";
|
||||
import Error from "../../Shared/Error";
|
||||
|
||||
import "react-datepicker/dist/react-datepicker.css";
|
||||
import "./shiftStartTimeOverrides.css";
|
||||
|
||||
const CShiftDurationOptions = [];
|
||||
for (let min = 60; min <= 480; min += 30) {
|
||||
let displayText = duration(min, "minutes").humanize();
|
||||
if (min % 60) {
|
||||
displayText = duration(Math.floor(min / 60), "hours").humanize();
|
||||
displayText += ` and ${duration(min % 60, "minutes").humanize()}`;
|
||||
}
|
||||
CShiftDurationOptions.push({
|
||||
key: min,
|
||||
value: min,
|
||||
text: displayText
|
||||
});
|
||||
}
|
||||
import { ClientShiftFormView } from "./ClientShiftFormView";
|
||||
|
||||
class ClientAddShiftForm extends Component {
|
||||
componentWillMount = () => {
|
||||
|
@ -177,7 +151,7 @@ class ClientAddShiftForm extends Component {
|
|||
key => shiftDates[key]
|
||||
);
|
||||
return (
|
||||
<ClientAddShiftFormView
|
||||
<ClientShiftFormView
|
||||
isSendingCShiftRequest={isSendingCShiftRequest}
|
||||
cShiftRequestErrors={cShiftRequestErrors}
|
||||
cShiftRequestSuccess={!!cShiftRequestSuccess.length}
|
||||
|
@ -206,124 +180,4 @@ function mapStateToProps(state) {
|
|||
return { ...state.cShift, selfUser: state.user.selfUser };
|
||||
}
|
||||
|
||||
const ClientAddShiftFormView = ({
|
||||
isSendingCShiftRequest,
|
||||
cShiftRequestErrors,
|
||||
cShiftRequestSuccess,
|
||||
user,
|
||||
employeeChoices,
|
||||
priceChoices,
|
||||
employeeUUID,
|
||||
priceUUID,
|
||||
startTime,
|
||||
duration,
|
||||
note,
|
||||
selectedShiftDates,
|
||||
changeSelectedEmployee,
|
||||
changeSelectedPrice,
|
||||
changeShiftStartTime,
|
||||
changeShiftDuration,
|
||||
changeShiftNote,
|
||||
handleSelectDate,
|
||||
onSubmitShifts
|
||||
}) => (
|
||||
<Container>
|
||||
<Header>Schedule Shifts</Header>
|
||||
<Form
|
||||
loading={isSendingCShiftRequest}
|
||||
onSubmit={onSubmitShifts}
|
||||
error={!!cShiftRequestErrors.length}
|
||||
success={!!cShiftRequestSuccess}
|
||||
>
|
||||
<Form.Group widths="equal">
|
||||
<Form.Field>
|
||||
<label>Employee</label>
|
||||
<Dropdown
|
||||
onChange={changeSelectedEmployee}
|
||||
options={employeeChoices}
|
||||
placeholder="Select employee"
|
||||
selection
|
||||
fluid
|
||||
search
|
||||
noResultsMessage="No approved employees found."
|
||||
value={employeeUUID}
|
||||
/>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<label>Price</label>
|
||||
<Dropdown
|
||||
onChange={changeSelectedPrice}
|
||||
options={priceChoices}
|
||||
placeholder="Select price"
|
||||
selection
|
||||
fluid
|
||||
search
|
||||
disabled={!employeeUUID}
|
||||
noResultsMessage="No prices for given employee."
|
||||
value={priceUUID}
|
||||
/>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<label>Shift Start Time</label>
|
||||
<DatePicker
|
||||
selected={startTime}
|
||||
onChange={changeShiftStartTime}
|
||||
showTimeSelect
|
||||
showTimeSelectOnly
|
||||
timeIntervals={30}
|
||||
dateFormat="LT Z"
|
||||
timeFormat="hh:mm"
|
||||
placeholderText="Select shift start time"
|
||||
/>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<label>Shift Duration</label>
|
||||
<Dropdown
|
||||
onChange={changeShiftDuration}
|
||||
options={CShiftDurationOptions}
|
||||
placeholder="Select duration"
|
||||
selection
|
||||
fluid
|
||||
value={duration}
|
||||
/>
|
||||
</Form.Field>
|
||||
</Form.Group>
|
||||
<Form.Field>
|
||||
<label>Note</label>
|
||||
<TextArea
|
||||
placeholder="Employee notes"
|
||||
value={note}
|
||||
onChange={changeShiftNote}
|
||||
/>
|
||||
</Form.Field>
|
||||
<Form.Field style={{ textAlign: "center" }}>
|
||||
<label>Dates</label>
|
||||
<DatePicker
|
||||
inline
|
||||
onSelect={handleSelectDate}
|
||||
highlightDates={selectedShiftDates}
|
||||
monthsShown={2}
|
||||
// https://github.com/Hacker0x01/react-datepicker/pull/1360
|
||||
peekNextMonth={false} // this is broken? Fixed in PR 1360
|
||||
minDate={utc(new Date()).add(1, "day")}
|
||||
maxDate={utc(new Date())
|
||||
.add(1, "month")
|
||||
.endOf("month")}
|
||||
/>
|
||||
</Form.Field>
|
||||
{!!cShiftRequestErrors.length && (
|
||||
<Error header="" error={cShiftRequestErrors[0]} />
|
||||
)}
|
||||
<Message success>
|
||||
<Message.Header>Add Shift successful!</Message.Header>
|
||||
<p>Shifts successfully scheduled.</p>
|
||||
{!!cShiftRequestSuccess && (
|
||||
<Redirect to="/user/profile/client/shifts" />
|
||||
)}
|
||||
</Message>
|
||||
<Form.Button>Schedule Shift</Form.Button>
|
||||
</Form>
|
||||
</Container>
|
||||
);
|
||||
|
||||
export default connect(mapStateToProps)(ClientAddShiftForm);
|
||||
|
|
237
src/components/User/Client/ClientEditShiftForm.jsx
Normal file
237
src/components/User/Client/ClientEditShiftForm.jsx
Normal file
|
@ -0,0 +1,237 @@
|
|||
import { utc, duration, ISO_8601 } from "moment";
|
||||
import React, { Component } from "react";
|
||||
import { connect } from "react-redux";
|
||||
import { Redirect } from "react-router-dom";
|
||||
import { Header, Label, Loader } from "semantic-ui-react";
|
||||
|
||||
import {
|
||||
setFormEmployeeUUID,
|
||||
setFormPriceUUID,
|
||||
setFormShiftStartTime,
|
||||
setFormShiftDuration,
|
||||
setFormShiftNote,
|
||||
setClearCShiftState,
|
||||
setFormShiftDates,
|
||||
setCShiftUUID
|
||||
} from "../../../actions/cShift/reducer.actions";
|
||||
import {
|
||||
getCShiftRequest,
|
||||
editCShiftRequest
|
||||
} from "../../../actions/cShift/saga.actions";
|
||||
import { ClientShiftFormView } from "./ClientShiftFormView";
|
||||
import { getEmployeeFromPrice } from "./ClientShiftShared";
|
||||
|
||||
class ClientEditShiftForm extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
const { cShiftRequestSuccess, selfUser } = this.props;
|
||||
if (selfUser.client && cShiftRequestSuccess.uuid) {
|
||||
const employee = getEmployeeFromPrice(
|
||||
cShiftRequestSuccess.price,
|
||||
selfUser
|
||||
);
|
||||
const startTime = utc(cShiftRequestSuccess.set_start, ISO_8601).local();
|
||||
const endTime = utc(cShiftRequestSuccess.set_end, ISO_8601).local();
|
||||
this.props.dispatch(setCShiftUUID(cShiftRequestSuccess.uuid));
|
||||
this.props.dispatch(setFormShiftDates([startTime]));
|
||||
this.props.dispatch(setFormShiftStartTime(startTime));
|
||||
this.props.dispatch(
|
||||
setFormShiftDuration(
|
||||
duration(endTime - startTime, "milliseconds").as("minutes")
|
||||
)
|
||||
);
|
||||
this.props.dispatch(setFormEmployeeUUID(employee.uuid));
|
||||
this.props.dispatch(setFormShiftNote(cShiftRequestSuccess.description));
|
||||
this.props.dispatch(setFormPriceUUID(cShiftRequestSuccess.price));
|
||||
}
|
||||
}
|
||||
|
||||
changeSelectedEmployee = (e, { value }) => {
|
||||
if (value !== this.props.employeeUUID) {
|
||||
this.props.dispatch(setFormPriceUUID(""));
|
||||
}
|
||||
this.props.dispatch(setFormEmployeeUUID(value));
|
||||
};
|
||||
|
||||
changeSelectedPrice = (e, { value }) => {
|
||||
this.props.dispatch(setFormPriceUUID(value));
|
||||
};
|
||||
|
||||
/**
|
||||
* change handler for shift start time selector.
|
||||
* @param momentTime - instance of moment (but we only care about the time)
|
||||
*/
|
||||
changeShiftStartTime = momentTime => {
|
||||
this.props.dispatch(setFormShiftStartTime(momentTime));
|
||||
};
|
||||
|
||||
changeShiftDuration = (e, { value }) => {
|
||||
this.props.dispatch(setFormShiftDuration(value));
|
||||
};
|
||||
|
||||
changeShiftNote = event => {
|
||||
this.props.dispatch(setFormShiftNote(event.target.value));
|
||||
};
|
||||
|
||||
/**
|
||||
* change handler for shift date selector
|
||||
* @param momentDate - instance of moment (but we only care about the day)
|
||||
*/
|
||||
handleSelectDate = momentDate => {
|
||||
this.props.dispatch(setFormShiftDates([momentDate]));
|
||||
};
|
||||
|
||||
onSubmitShifts = event => {
|
||||
event.preventDefault();
|
||||
// change this into interable cshift post request bodies
|
||||
const {
|
||||
cShiftUUID,
|
||||
priceUUID,
|
||||
startTime,
|
||||
duration,
|
||||
note,
|
||||
shiftDates
|
||||
} = this.props;
|
||||
const postRequestBodies = [];
|
||||
for (let shiftDateString in shiftDates) {
|
||||
const dynamicStartTime = utc(startTime);
|
||||
const startDate = shiftDates[shiftDateString];
|
||||
dynamicStartTime.set({
|
||||
year: startDate.get("year"),
|
||||
month: startDate.get("month"),
|
||||
date: startDate.get("date")
|
||||
});
|
||||
const dynamicEndTime = utc(dynamicStartTime);
|
||||
dynamicEndTime.add(duration, "minutes");
|
||||
postRequestBodies.push({
|
||||
get_price_uuid: priceUUID,
|
||||
set_start: dynamicStartTime.format(),
|
||||
set_end: dynamicEndTime.format(),
|
||||
description: note ? note : undefined
|
||||
});
|
||||
}
|
||||
console.log({ ...postRequestBodies[0], uuid: cShiftUUID })
|
||||
this.props.dispatch(
|
||||
editCShiftRequest({ ...postRequestBodies[0], uuid: cShiftUUID })
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
isSendingCShiftRequest,
|
||||
cShiftRequestErrors,
|
||||
cShiftRequestSuccess,
|
||||
selfUser,
|
||||
employeeUUID,
|
||||
priceUUID,
|
||||
startTime,
|
||||
duration,
|
||||
note,
|
||||
shiftDates,
|
||||
cShiftUUID
|
||||
} = this.props;
|
||||
|
||||
if (!selfUser.client) {
|
||||
return <Redirect to="/" />;
|
||||
}
|
||||
if (cShiftUUID === true) {
|
||||
return <Redirect to="/user/profile/client/shifts" />;
|
||||
}
|
||||
|
||||
const employeeChoices = selfUser.client.employees
|
||||
// TODO: ugly edit of state changed employee
|
||||
.filter(employee => !employee.deleted && !!employee.approved)
|
||||
.map(({ uuid, provider }) => ({
|
||||
key: uuid,
|
||||
value: uuid,
|
||||
text: provider.email
|
||||
}));
|
||||
|
||||
const priceChoices = [];
|
||||
if (employeeUUID) {
|
||||
const employee = selfUser.client.employees.find(emp => {
|
||||
return emp && emp.uuid === employeeUUID;
|
||||
});
|
||||
priceChoices.push(
|
||||
...employee.prices
|
||||
.filter(price => !price.deleted)
|
||||
.map(({ amount, uuid, work_type }) => ({
|
||||
key: uuid,
|
||||
value: uuid,
|
||||
text: `${work_type.label} ($${amount}/hr)`,
|
||||
content: (
|
||||
<Header>
|
||||
<Label
|
||||
circular
|
||||
empty
|
||||
style={{
|
||||
backgroundColor: work_type.color,
|
||||
borderColor: work_type.color
|
||||
}}
|
||||
/>
|
||||
{work_type.label}
|
||||
<Header.Subheader
|
||||
style={{ paddingLeft: "2em" }}
|
||||
content={`Hourly Rate: ${amount}`}
|
||||
/>
|
||||
</Header>
|
||||
)
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
||||
const selectedShiftDates = Object.keys(shiftDates).map(
|
||||
key => shiftDates[key]
|
||||
);
|
||||
return (
|
||||
<ClientShiftFormView
|
||||
isSendingCShiftRequest={isSendingCShiftRequest}
|
||||
cShiftRequestErrors={cShiftRequestErrors}
|
||||
cShiftRequestSuccess={!!cShiftRequestSuccess.length}
|
||||
user={selfUser}
|
||||
employeeChoices={employeeChoices}
|
||||
priceChoices={priceChoices}
|
||||
employeeUUID={employeeUUID}
|
||||
priceUUID={priceUUID}
|
||||
startTime={startTime}
|
||||
duration={duration}
|
||||
note={note}
|
||||
selectedShiftDates={selectedShiftDates}
|
||||
changeSelectedEmployee={this.changeSelectedEmployee}
|
||||
changeSelectedPrice={this.changeSelectedPrice}
|
||||
changeShiftStartTime={this.changeShiftStartTime}
|
||||
changeShiftDuration={this.changeShiftDuration}
|
||||
changeShiftNote={this.changeShiftNote}
|
||||
handleSelectDate={this.handleSelectDate}
|
||||
onSubmitShifts={this.onSubmitShifts}
|
||||
isEditing={true}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return { ...state.cShift, selfUser: state.user.selfUser };
|
||||
}
|
||||
|
||||
class EditClientShiftWrapper extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props.dispatch(setClearCShiftState());
|
||||
this.props.dispatch(
|
||||
getCShiftRequest({ uuid: this.props.match.params.shiftUUID })
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { cShiftRequestSuccess } = this.props;
|
||||
if (cShiftRequestSuccess.uuid) {
|
||||
return <ClientEditShiftForm {...this.props} />;
|
||||
} else {
|
||||
return <Loader />;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(EditClientShiftWrapper);
|
159
src/components/User/Client/ClientShiftFormView.jsx
Normal file
159
src/components/User/Client/ClientShiftFormView.jsx
Normal file
|
@ -0,0 +1,159 @@
|
|||
import { utc, duration } from "moment";
|
||||
import React from "react";
|
||||
import DatePicker from "react-datepicker";
|
||||
import { Redirect } from "react-router-dom";
|
||||
import {
|
||||
Container,
|
||||
Dropdown,
|
||||
Form,
|
||||
Header,
|
||||
Message,
|
||||
TextArea
|
||||
} from "semantic-ui-react";
|
||||
|
||||
import Error from "../../Shared/Error";
|
||||
import "react-datepicker/dist/react-datepicker.css";
|
||||
import "./shiftStartTimeOverrides.css";
|
||||
|
||||
const CShiftDurationOptions = [];
|
||||
for (let min = 60; min <= 480; min += 30) {
|
||||
let displayText = duration(min, "minutes").humanize();
|
||||
if (min % 60) {
|
||||
displayText = duration(Math.floor(min / 60), "hours").humanize();
|
||||
displayText += ` and ${duration(min % 60, "minutes").humanize()}`;
|
||||
}
|
||||
CShiftDurationOptions.push({
|
||||
key: min,
|
||||
value: min,
|
||||
text: displayText
|
||||
});
|
||||
}
|
||||
|
||||
export const ClientShiftFormView = ({
|
||||
isSendingCShiftRequest,
|
||||
cShiftRequestErrors,
|
||||
cShiftRequestSuccess,
|
||||
user,
|
||||
employeeChoices,
|
||||
priceChoices,
|
||||
employeeUUID,
|
||||
priceUUID,
|
||||
startTime,
|
||||
duration,
|
||||
note,
|
||||
selectedShiftDates,
|
||||
changeSelectedEmployee,
|
||||
changeSelectedPrice,
|
||||
changeShiftStartTime,
|
||||
changeShiftDuration,
|
||||
changeShiftNote,
|
||||
handleSelectDate,
|
||||
onSubmitShifts,
|
||||
isEditing = false
|
||||
}) => (
|
||||
<Container>
|
||||
<Header>
|
||||
{!isEditing && "Schedule Shifts"}
|
||||
{isEditing && "Edit Shift"}
|
||||
</Header>
|
||||
<Form
|
||||
loading={isSendingCShiftRequest}
|
||||
onSubmit={onSubmitShifts}
|
||||
error={!!cShiftRequestErrors.length}
|
||||
success={!!cShiftRequestSuccess}
|
||||
>
|
||||
<Form.Group widths="equal">
|
||||
<Form.Field>
|
||||
<label>Employee</label>
|
||||
<Dropdown
|
||||
onChange={changeSelectedEmployee}
|
||||
options={employeeChoices}
|
||||
placeholder="Select employee"
|
||||
selection
|
||||
fluid
|
||||
search
|
||||
noResultsMessage="No approved employees found."
|
||||
value={employeeUUID}
|
||||
/>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<label>Price</label>
|
||||
<Dropdown
|
||||
onChange={changeSelectedPrice}
|
||||
options={priceChoices}
|
||||
placeholder="Select price"
|
||||
selection
|
||||
fluid
|
||||
search
|
||||
disabled={!employeeUUID}
|
||||
noResultsMessage="No prices for given employee."
|
||||
value={priceUUID}
|
||||
/>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<label>Shift Start Time</label>
|
||||
<DatePicker
|
||||
selected={startTime}
|
||||
onChange={changeShiftStartTime}
|
||||
showTimeSelect
|
||||
showTimeSelectOnly
|
||||
timeIntervals={30}
|
||||
dateFormat="LT Z"
|
||||
timeFormat="hh:mm"
|
||||
placeholderText="Select shift start time"
|
||||
/>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<label>Shift Duration</label>
|
||||
<Dropdown
|
||||
onChange={changeShiftDuration}
|
||||
options={CShiftDurationOptions}
|
||||
placeholder="Select duration"
|
||||
selection
|
||||
fluid
|
||||
value={duration}
|
||||
/>
|
||||
</Form.Field>
|
||||
</Form.Group>
|
||||
<Form.Field>
|
||||
<label>Note</label>
|
||||
<TextArea
|
||||
placeholder="Employee notes"
|
||||
value={note}
|
||||
onChange={changeShiftNote}
|
||||
/>
|
||||
</Form.Field>
|
||||
<Form.Field style={{ textAlign: "center" }}>
|
||||
<label>Dates</label>
|
||||
<DatePicker
|
||||
inline
|
||||
onSelect={handleSelectDate}
|
||||
highlightDates={selectedShiftDates}
|
||||
monthsShown={2}
|
||||
// https://github.com/Hacker0x01/react-datepicker/pull/1360
|
||||
peekNextMonth={false} // this is broken? Fixed in PR 1360
|
||||
minDate={utc(new Date()).add(1, "day")}
|
||||
maxDate={utc(new Date())
|
||||
.add(1, "month")
|
||||
.endOf("month")}
|
||||
/>
|
||||
</Form.Field>
|
||||
{!!cShiftRequestErrors.length && (
|
||||
<Error header="" error={cShiftRequestErrors[0]} />
|
||||
)}
|
||||
<Message success>
|
||||
<Message.Header>Add Shift successful!</Message.Header>
|
||||
<p>Shifts successfully scheduled.</p>
|
||||
{!!cShiftRequestSuccess && (
|
||||
<Redirect to="/user/profile/client/shifts" />
|
||||
)}
|
||||
</Message>
|
||||
<Form.Button>
|
||||
{!isEditing && "Schedule Shifts"}
|
||||
{isEditing && "Edit Shift"}
|
||||
</Form.Button>
|
||||
</Form>
|
||||
</Container>
|
||||
);
|
||||
|
||||
export default ClientShiftFormView;
|
13
src/components/User/Client/ClientShiftShared.js
Normal file
13
src/components/User/Client/ClientShiftShared.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
export const getEmployeeFromPrice = (priceUUID, selfUser) => {
|
||||
const employees = selfUser && selfUser.client && selfUser.client.employees;
|
||||
let matchEmployee = null;
|
||||
employees.forEach(employee => {
|
||||
const priceMatch = employee.prices.filter(price => {
|
||||
return price.uuid === priceUUID;
|
||||
});
|
||||
if (priceMatch.length > 0) {
|
||||
matchEmployee = employee;
|
||||
}
|
||||
});
|
||||
return matchEmployee;
|
||||
};
|
|
@ -7,7 +7,8 @@ import {
|
|||
Header,
|
||||
Item,
|
||||
Segment,
|
||||
Pagination
|
||||
Pagination,
|
||||
Loader
|
||||
} from "semantic-ui-react";
|
||||
import { getCShiftsRequest } from "../../../actions/cShift/saga.actions";
|
||||
|
||||
|
@ -91,15 +92,29 @@ const ClientShiftsView = ({
|
|||
Schedule a Shift
|
||||
</Button>
|
||||
</Segment>
|
||||
{!!isSendingCShiftRequest && <Loader content="Loading" />}
|
||||
{!isSendingCShiftRequest &&
|
||||
results.length > 0 && (
|
||||
<Item.Group>
|
||||
<Item.Group divided>
|
||||
{results.map(result => (
|
||||
<Item key={result.uuid}>
|
||||
<Item.Content>
|
||||
<Item.Header content={result.uuid} />
|
||||
<code>{JSON.stringify(result, null, 2)}</code>
|
||||
</Item.Content>
|
||||
<Item.Extra>
|
||||
<Button
|
||||
primary
|
||||
floated="right"
|
||||
as={Link}
|
||||
to={`/user/profile/client/edit-shift/${result.uuid}`}
|
||||
>
|
||||
Edit
|
||||
</Button>
|
||||
<Button color="red" floated="right">
|
||||
Delete
|
||||
</Button>
|
||||
</Item.Extra>
|
||||
</Item>
|
||||
))}
|
||||
</Item.Group>
|
||||
|
|
|
@ -10,8 +10,11 @@ export const SET_FORM_SHIFT_START_TIME = "SET_FORM_SHIFT_START_TIME";
|
|||
export const SET_FORM_SHIFT_DURATION = "SET_FORM_SHIFT_DURATION";
|
||||
export const SET_FORM_SHIFT_NOTE = "SET_FORM_SHIFT_NOTE";
|
||||
export const SET_FORM_SHIFT_DATES = "SET_FORM_SHIFT_DATES";
|
||||
export const SET_CSHIFT_UUID = "SET_CSHIFT_UUID";
|
||||
export const SET_CLEAR_CSHIFT_STATE = "SET_CLEAR_CSHIFT_STATE";
|
||||
|
||||
// Saga CShift Action Constants
|
||||
export const CREATE_MULTIPLE_CSHIFT_REQUEST = "CREATE_MULTIPLE_CSHIFT_REQUEST";
|
||||
export const GET_CSHIFTS_REQUEST = "GET_CSHIFTS_REQUEST";
|
||||
export const GET_CSHIFT_REQUEST = "GET_CSHIFT_REQUEST";
|
||||
export const EDIT_CSHIFT_REQUEST = "EDIT_CSHIFT_REQUEST";
|
||||
|
|
|
@ -10,6 +10,7 @@ import {
|
|||
SET_FORM_SHIFT_DURATION,
|
||||
SET_FORM_SHIFT_NOTE,
|
||||
SET_FORM_SHIFT_DATES,
|
||||
SET_CSHIFT_UUID,
|
||||
SET_CLEAR_CSHIFT_STATE
|
||||
} from "../constants/cShift.constants";
|
||||
|
||||
|
@ -22,7 +23,8 @@ const initialState = {
|
|||
startTime: null, // When does the shift begin? moment instance
|
||||
duration: "", // Duration of shift in minutes
|
||||
note: "", // Optional note
|
||||
shiftDates: {} // Dates, map of "YYYY-MM-DD" > moment instance
|
||||
shiftDates: {}, // Dates, map of "YYYY-MM-DD" > moment instance
|
||||
cShiftUUID: ""
|
||||
};
|
||||
|
||||
function cShiftReducer(state = initialState, action) {
|
||||
|
@ -82,6 +84,11 @@ function cShiftReducer(state = initialState, action) {
|
|||
...state,
|
||||
shiftDates: action.data
|
||||
};
|
||||
case SET_CSHIFT_UUID:
|
||||
return {
|
||||
...state,
|
||||
cShiftUUID: action.data
|
||||
};
|
||||
case SET_CLEAR_CSHIFT_STATE:
|
||||
return {
|
||||
...initialState
|
||||
|
|
|
@ -11,9 +11,15 @@ import {
|
|||
setFormShiftDates,
|
||||
setFormShiftDuration,
|
||||
setFormShiftNote,
|
||||
setFormShiftStartTime
|
||||
setFormShiftStartTime,
|
||||
setCShiftUUID
|
||||
} from "../actions/cShift/reducer.actions";
|
||||
import { createCShifts, getCShifts } from "../api/cShift.api";
|
||||
import {
|
||||
createCShifts,
|
||||
getCShifts,
|
||||
getCShift,
|
||||
editCShift
|
||||
} from "../api/cShift.api";
|
||||
|
||||
function* createCShiftsCall(postBodies) {
|
||||
yield effects.put(isSendingCShiftRequest(true));
|
||||
|
@ -48,6 +54,32 @@ function* getCShiftsCall(params) {
|
|||
}
|
||||
}
|
||||
|
||||
function* getCShiftCall({ uuid, params }) {
|
||||
yield effects.put(isSendingCShiftRequest(true));
|
||||
try {
|
||||
return yield effects.call(getCShift, uuid, params);
|
||||
} catch (exception) {
|
||||
yield effects.put(setCShiftRequestError(exception));
|
||||
return false;
|
||||
} finally {
|
||||
yield effects.put(isSendingCShiftRequest(false));
|
||||
}
|
||||
}
|
||||
|
||||
function* editCShiftCall(payload) {
|
||||
yield effects.put(isSendingCShiftRequest(true));
|
||||
try {
|
||||
const edit = yield effects.call(editCShift, payload.uuid, payload);
|
||||
yield effects.put(setCShiftUUID(true));
|
||||
return edit;
|
||||
} catch (exception) {
|
||||
yield effects.put(setCShiftRequestError(exception));
|
||||
return false;
|
||||
} finally {
|
||||
yield effects.put(isSendingCShiftRequest(false));
|
||||
}
|
||||
}
|
||||
|
||||
export function* createCShiftsFlow(request) {
|
||||
yield effects.put(clearCShiftRequestSuccess());
|
||||
yield effects.put(clearCShiftRequestError());
|
||||
|
@ -78,3 +110,20 @@ export function* getCShiftsFlow(request) {
|
|||
yield effects.put(setCShiftRequestSuccess(isSuccessful));
|
||||
}
|
||||
}
|
||||
|
||||
export function* getCShiftFlow(request) {
|
||||
yield effects.put(clearCShiftRequestSuccess());
|
||||
yield effects.put(clearCShiftRequestError());
|
||||
const wasSuccessful = yield effects.call(getCShiftCall, request.data);
|
||||
if (wasSuccessful) {
|
||||
yield effects.put(setCShiftRequestSuccess(wasSuccessful));
|
||||
}
|
||||
}
|
||||
|
||||
export function* editCShiftFlow(request) {
|
||||
yield effects.put(clearCShiftRequestError());
|
||||
const wasSuccessful = yield effects.call(editCShiftCall, request.data);
|
||||
if (wasSuccessful) {
|
||||
yield effects.put(setCShiftRequestSuccess(wasSuccessful));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,9 +71,16 @@ import {
|
|||
} from "./price.sagas";
|
||||
import {
|
||||
CREATE_MULTIPLE_CSHIFT_REQUEST,
|
||||
GET_CSHIFTS_REQUEST
|
||||
GET_CSHIFTS_REQUEST,
|
||||
GET_CSHIFT_REQUEST,
|
||||
EDIT_CSHIFT_REQUEST
|
||||
} from "../constants/cShift.constants";
|
||||
import { createCShiftsFlow, getCShiftsFlow } from "./cShift.sagas";
|
||||
import {
|
||||
createCShiftsFlow,
|
||||
getCShiftsFlow,
|
||||
getCShiftFlow,
|
||||
editCShiftFlow
|
||||
} from "./cShift.sagas";
|
||||
|
||||
export default function* rootSaga() {
|
||||
yield takeLatest(SEND_REGISTER_REQUEST, registerUserFlow);
|
||||
|
@ -103,4 +110,6 @@ export default function* rootSaga() {
|
|||
yield takeLatest(DELETE_PRICE_REQUEST, deletePriceFlow);
|
||||
yield takeLatest(CREATE_MULTIPLE_CSHIFT_REQUEST, createCShiftsFlow);
|
||||
yield takeLatest(GET_CSHIFTS_REQUEST, getCShiftsFlow);
|
||||
yield takeLatest(GET_CSHIFT_REQUEST, getCShiftFlow);
|
||||
yield takeLatest(EDIT_CSHIFT_REQUEST, editCShiftFlow);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user