Fully functional widgets for adding shifts

- todo: wait for React Datepicker PR 1380
- batch api call and saga handlers
- view/edit
This commit is contained in:
Alexander Wong 2018-04-19 10:30:33 -06:00
parent 0c8defd469
commit 530593b721
No known key found for this signature in database
GPG Key ID: E90E5D6448C2C663
5 changed files with 117 additions and 22 deletions

View File

@ -6,9 +6,11 @@ import {
CLEAR_CSHIFT_REQUEST_SUCCESS, CLEAR_CSHIFT_REQUEST_SUCCESS,
SET_FORM_EMPLOYEE_UUID, SET_FORM_EMPLOYEE_UUID,
SET_FORM_PRICE_UUID, SET_FORM_PRICE_UUID,
SET_CLEAR_CSHIFT_STATE,
SET_FORM_SHIFT_START_TIME, SET_FORM_SHIFT_START_TIME,
SET_FORM_SHIFT_DURATION SET_FORM_SHIFT_DURATION,
SET_FORM_SHIFT_NOTE,
SET_FORM_SHIFT_DATES,
SET_CLEAR_CSHIFT_STATE
} from "../../constants/cShift.constants"; } from "../../constants/cShift.constants";
import { parseError } from "../common.actions"; import { parseError } from "../common.actions";
@ -74,6 +76,20 @@ export function setFormShiftDuration(duration) {
}; };
} }
export function setFormShiftNote(note) {
return {
type: SET_FORM_SHIFT_NOTE,
data: note
};
}
export function setFormShiftDates(dates) {
return {
type: SET_FORM_SHIFT_DATES,
data: dates
};
}
export function setClearCshiftState() { export function setClearCshiftState() {
return { return {
type: SET_CLEAR_CSHIFT_STATE type: SET_CLEAR_CSHIFT_STATE

View File

@ -1,4 +1,4 @@
import { duration } from "moment"; import { duration, utc } from "moment";
import React, { Component } from "react"; import React, { Component } from "react";
import DatePicker from "react-datepicker"; import DatePicker from "react-datepicker";
import { connect } from "react-redux"; import { connect } from "react-redux";
@ -17,7 +17,9 @@ import {
setFormPriceUUID, setFormPriceUUID,
setFormShiftStartTime, setFormShiftStartTime,
setFormShiftDuration, setFormShiftDuration,
setClearCshiftState setFormShiftNote,
setClearCshiftState,
setFormShiftDates
} from "../../../actions/cShift/reducer.actions"; } from "../../../actions/cShift/reducer.actions";
import "react-datepicker/dist/react-datepicker.css"; import "react-datepicker/dist/react-datepicker.css";
@ -28,7 +30,7 @@ for (let min = 60; min <= 480; min += 30) {
let displayText = duration(min, "minutes").humanize(); let displayText = duration(min, "minutes").humanize();
if (min % 60) { if (min % 60) {
displayText = duration(Math.floor(min / 60), "hours").humanize(); displayText = duration(Math.floor(min / 60), "hours").humanize();
displayText += ", " + duration(min % 60, "minutes").humanize(); displayText += ` and ${duration(min % 60, "minutes").humanize()}`;
} }
CShiftDurationOptions.push({ CShiftDurationOptions.push({
key: min, key: min,
@ -55,23 +57,44 @@ class ClientAddShiftForm extends Component {
/** /**
* change handler for shift start time selector. * change handler for shift start time selector.
* @param date - instance of moment * @param momentTime - instance of moment (but we only care about the time)
*/ */
changeShiftStartTime = date => { changeShiftStartTime = momentTime => {
this.props.dispatch(setFormShiftStartTime(date)); this.props.dispatch(setFormShiftStartTime(momentTime));
}; };
changeShiftDuration = (e, { value }) => { changeShiftDuration = (e, { value }) => {
this.props.dispatch(setFormShiftDuration(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 => {
const shiftDatesCopy = { ...this.props.shiftDates };
const key = momentDate.format("YYYY-MM-DD");
if (shiftDatesCopy.hasOwnProperty(key)) {
delete shiftDatesCopy[key];
} else {
shiftDatesCopy[key] = momentDate;
}
this.props.dispatch(setFormShiftDates(shiftDatesCopy));
};
render() { render() {
const { const {
selfUser, selfUser,
employeeUUID, employeeUUID,
priceUUID, priceUUID,
startTime, startTime,
duration duration,
note,
shiftDates
} = this.props; } = this.props;
if (!selfUser.client) { if (!selfUser.client) {
@ -118,6 +141,10 @@ class ClientAddShiftForm extends Component {
})) }))
); );
} }
const selectedShiftDates = Object.keys(shiftDates).map(
key => shiftDates[key]
);
return ( return (
<ClientAddShiftFormView <ClientAddShiftFormView
user={selfUser} user={selfUser}
@ -127,10 +154,14 @@ class ClientAddShiftForm extends Component {
priceUUID={priceUUID} priceUUID={priceUUID}
startTime={startTime} startTime={startTime}
duration={duration} duration={duration}
note={note}
selectedShiftDates={selectedShiftDates}
changeSelectedEmployee={this.changeSelectedEmployee} changeSelectedEmployee={this.changeSelectedEmployee}
changeSelectedPrice={this.changeSelectedPrice} changeSelectedPrice={this.changeSelectedPrice}
changeShiftStartTime={this.changeShiftStartTime} changeShiftStartTime={this.changeShiftStartTime}
changeShiftDuration={this.changeShiftDuration} changeShiftDuration={this.changeShiftDuration}
changeShiftNote={this.changeShiftNote}
handleSelectDate={this.handleSelectDate}
/> />
); );
} }
@ -148,13 +179,17 @@ const ClientAddShiftFormView = ({
priceUUID, priceUUID,
startTime, startTime,
duration, duration,
note,
selectedShiftDates,
changeSelectedEmployee, changeSelectedEmployee,
changeSelectedPrice, changeSelectedPrice,
changeShiftStartTime, changeShiftStartTime,
changeShiftDuration changeShiftDuration,
changeShiftNote,
handleSelectDate
}) => ( }) => (
<Container> <Container>
<Header>Schedule a Shift</Header> <Header>Schedule Shifts</Header>
<Form> <Form>
<Form.Group widths="equal"> <Form.Group widths="equal">
<Form.Field> <Form.Field>
@ -210,11 +245,26 @@ const ClientAddShiftFormView = ({
</Form.Group> </Form.Group>
<Form.Field> <Form.Field>
<label>Note</label> <label>Note</label>
<TextArea placeholder="Employee notes" /> <TextArea
placeholder="Employee notes"
value={note}
onChange={changeShiftNote}
/>
</Form.Field> </Form.Field>
<Form.Field> <Form.Field style={{ textAlign: "center" }}>
<label>Days</label> <label>Dates</label>
<TextArea placeholder="Date Picker" /> <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> </Form.Field>
<Form.Button>Schedule Shift</Form.Button> <Form.Button>Schedule Shift</Form.Button>
</Form> </Form>

View File

@ -19,7 +19,7 @@
padding-right: 0; padding-right: 0;
} }
/* next two required because datepicker ignores fluid anyways */ /* next two required because datepicker input ignores fluid anyways */
#root #root
> div > div
> div:nth-child(2) > div:nth-child(2)
@ -46,3 +46,17 @@
> div { > div {
width: 100%; width: 100%;
} }
/* required so the inline two months view still looks decent on mobile */
@media only screen and (max-width: 470px) {
#root
> div
> div:nth-child(2)
> div:nth-child(1)
> div
> form
> div:nth-child(3)
> div {
width: min-content;
}
}

View File

@ -6,9 +6,10 @@ export const SET_CSHIFT_REQUEST_SUCCESS = "SET_CSHIFT_REQUEST_SUCCESS";
export const CLEAR_CSHIFT_REQUEST_SUCCESS = "CLEAR_CSHIFT_REQUEST_SUCCESS"; export const CLEAR_CSHIFT_REQUEST_SUCCESS = "CLEAR_CSHIFT_REQUEST_SUCCESS";
export const SET_FORM_EMPLOYEE_UUID = "SET_FORM_EMPLOYEE_UUID"; export const SET_FORM_EMPLOYEE_UUID = "SET_FORM_EMPLOYEE_UUID";
export const SET_FORM_PRICE_UUID = "SET_FORM_PRICE_UUID"; export const SET_FORM_PRICE_UUID = "SET_FORM_PRICE_UUID";
export const SET_FORM_SHIFT_START_TIME = "SET_FORM_SHIFT_START_TIME" 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_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_CLEAR_CSHIFT_STATE = "SET_CLEAR_CSHIFT_STATE"; export const SET_CLEAR_CSHIFT_STATE = "SET_CLEAR_CSHIFT_STATE";
// Saga CShift Action Constants // Saga CShift Action Constants

View File

@ -8,6 +8,8 @@ import {
SET_FORM_PRICE_UUID, SET_FORM_PRICE_UUID,
SET_FORM_SHIFT_START_TIME, SET_FORM_SHIFT_START_TIME,
SET_FORM_SHIFT_DURATION, SET_FORM_SHIFT_DURATION,
SET_FORM_SHIFT_NOTE,
SET_FORM_SHIFT_DATES,
SET_CLEAR_CSHIFT_STATE SET_CLEAR_CSHIFT_STATE
} from "../constants/cShift.constants"; } from "../constants/cShift.constants";
@ -15,10 +17,12 @@ const initialState = {
isSendingCShiftRequest: false, isSendingCShiftRequest: false,
cShiftRequestError: "", cShiftRequestError: "",
cShiftRequestSuccess: "", cShiftRequestSuccess: "",
employeeUUID: "", employeeUUID: "", // Which employee
priceUUID: "", priceUUID: "", // Which price
startTime: null, startTime: null, // When does the shift begin? moment instance
duration: 60 duration: "", // Duration of shift in minutes
note: "", // Optional note
shiftDates: {} // Dates, map of "YYYY-MM-DD" > moment instance
}; };
function cShiftReducer(state = initialState, action) { function cShiftReducer(state = initialState, action) {
@ -68,6 +72,16 @@ function cShiftReducer(state = initialState, action) {
...state, ...state,
duration: action.data duration: action.data
}; };
case SET_FORM_SHIFT_NOTE:
return {
...state,
note: action.data
};
case SET_FORM_SHIFT_DATES:
return {
...state,
shiftDates: action.data
};
case SET_CLEAR_CSHIFT_STATE: case SET_CLEAR_CSHIFT_STATE:
return { return {
...initialState ...initialState