added functional duration/time selector

This commit is contained in:
Alexander Wong 2018-04-18 16:50:02 -06:00
parent 99dc3a9615
commit 0c8defd469
No known key found for this signature in database
GPG Key ID: E90E5D6448C2C663
7 changed files with 190 additions and 25 deletions

View File

@ -5,8 +5,10 @@
"dependencies": {
"axios": "^0.18.0",
"localStorage": "^1.0.3",
"moment": "^2.22.1",
"react": "^16.2.0",
"react-color": "^2.13.8",
"react-datepicker": "^1.4.1",
"react-dom": "^16.2.0",
"react-redux": "^5.0.6",
"react-router": "^4.2.0",

View File

@ -6,7 +6,9 @@ import {
CLEAR_CSHIFT_REQUEST_SUCCESS,
SET_FORM_EMPLOYEE_UUID,
SET_FORM_PRICE_UUID,
SET_CLEAR_CSHIFT_STATE
SET_CLEAR_CSHIFT_STATE,
SET_FORM_SHIFT_START_TIME,
SET_FORM_SHIFT_DURATION
} from "../../constants/cShift.constants";
import { parseError } from "../common.actions";
@ -58,6 +60,20 @@ export function setFormPriceUUID(uuid) {
};
}
export function setFormShiftStartTime(startTime) {
return {
type: SET_FORM_SHIFT_START_TIME,
data: startTime
};
}
export function setFormShiftDuration(duration) {
return {
type: SET_FORM_SHIFT_DURATION,
data: duration
};
}
export function setClearCshiftState() {
return {
type: SET_CLEAR_CSHIFT_STATE

View File

@ -1,4 +1,6 @@
import { duration } from "moment";
import React, { Component } from "react";
import DatePicker from "react-datepicker";
import { connect } from "react-redux";
import { Redirect } from "react-router-dom";
import {
@ -6,24 +8,38 @@ import {
Dropdown,
Form,
Header,
Input,
Label,
TextArea
} from "semantic-ui-react";
import {
clearCShiftRequestError,
clearCShiftRequestSuccess,
setFormEmployeeUUID,
setFormPriceUUID
setFormPriceUUID,
setFormShiftStartTime,
setFormShiftDuration,
setClearCshiftState
} from "../../../actions/cShift/reducer.actions";
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 += ", " + duration(min % 60, "minutes").humanize();
}
CShiftDurationOptions.push({
key: min,
value: min,
text: displayText
});
}
class ClientAddShiftForm extends Component {
componentWillMount = () => {
this.props.dispatch(clearCShiftRequestError());
this.props.dispatch(clearCShiftRequestSuccess());
this.props.dispatch(setFormEmployeeUUID(""));
this.props.dispatch(setFormPriceUUID(""));
this.props.dispatch(setClearCshiftState());
};
changeSelectedEmployee = (e, { value }) => {
@ -37,8 +53,26 @@ class ClientAddShiftForm extends Component {
this.props.dispatch(setFormPriceUUID(value));
};
/**
* change handler for shift start time selector.
* @param date - instance of moment
*/
changeShiftStartTime = date => {
this.props.dispatch(setFormShiftStartTime(date));
};
changeShiftDuration = (e, { value }) => {
this.props.dispatch(setFormShiftDuration(value));
};
render() {
const { selfUser, employeeUUID, priceUUID } = this.props;
const {
selfUser,
employeeUUID,
priceUUID,
startTime,
duration
} = this.props;
if (!selfUser.client) {
return <Redirect to="/" />;
@ -51,6 +85,7 @@ class ClientAddShiftForm extends Component {
value: uuid,
text: provider.email
}));
const priceChoices = [];
if (employeeUUID) {
const employee = selfUser.client.employees.find(emp => {
@ -90,8 +125,12 @@ class ClientAddShiftForm extends Component {
priceChoices={priceChoices}
employeeUUID={employeeUUID}
priceUUID={priceUUID}
startTime={startTime}
duration={duration}
changeSelectedEmployee={this.changeSelectedEmployee}
changeSelectedPrice={this.changeSelectedPrice}
changeShiftStartTime={this.changeShiftStartTime}
changeShiftDuration={this.changeShiftDuration}
/>
);
}
@ -107,8 +146,12 @@ const ClientAddShiftFormView = ({
priceChoices,
employeeUUID,
priceUUID,
startTime,
duration,
changeSelectedEmployee,
changeSelectedPrice
changeSelectedPrice,
changeShiftStartTime,
changeShiftDuration
}) => (
<Container>
<Header>Schedule a Shift</Header>
@ -117,40 +160,52 @@ const ClientAddShiftFormView = ({
<Form.Field>
<label>Employee</label>
<Dropdown
onChange={changeSelectedEmployee}
options={employeeChoices}
placeholder="Select employee"
openOnFocus
closeOnBlur
selection
fluid
search
options={employeeChoices}
noResultsMessage="No approved employees found."
onChange={changeSelectedEmployee}
value={employeeUUID}
/>
</Form.Field>
<Form.Field>
<label>Price</label>
<Dropdown
onChange={changeSelectedPrice}
options={priceChoices}
placeholder="Select price"
openOnFocus
closeOnBlur
selection
fluid
search
options={priceChoices}
noResultsMessage="No prices for given employee."
onChange={changeSelectedPrice}
value={priceUUID}
/>
</Form.Field>
<Form.Field>
<label>Time</label>
<Input placeholder="Time" type="text" />
<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>Duration</label>
<Input placeholder="Duration" type="text" />
<label>Shift Duration</label>
<Dropdown
onChange={changeShiftDuration}
options={CShiftDurationOptions}
placeholder="Select duration"
selection
fluid
value={duration}
/>
</Form.Field>
</Form.Group>
<Form.Field>

View File

@ -0,0 +1,48 @@
/* inline CSS style overrides for client shift start time picker */
/* required, datepicker popper inherits padding of parent field width */
#root
> div
> div:nth-child(2)
> div:nth-child(1)
> div
> form
> div.equal.width.fields
> div:nth-child(3)
> div
> div.react-datepicker-popper
> div
> div.react-datepicker__time-container
> div.react-datepicker__time
> div
> ul {
padding-left: 0;
padding-right: 0;
}
/* next two required because datepicker ignores fluid anyways */
#root
> div
> div:nth-child(2)
> div:nth-child(1)
> div
> form
> div.equal.width.fields
> div:nth-child(3)
> div
> div.react-datepicker-wrapper {
width: 100%;
}
#root
> div
> div:nth-child(2)
> div:nth-child(1)
> div
> form
> div.equal.width.fields
> div:nth-child(3)
> div
> div
> div {
width: 100%;
}

View File

@ -6,6 +6,8 @@ export const SET_CSHIFT_REQUEST_SUCCESS = "SET_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_PRICE_UUID = "SET_FORM_PRICE_UUID";
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_CLEAR_CSHIFT_STATE = "SET_CLEAR_CSHIFT_STATE";

View File

@ -6,6 +6,8 @@ import {
CLEAR_CSHIFT_REQUEST_SUCCESS,
SET_FORM_EMPLOYEE_UUID,
SET_FORM_PRICE_UUID,
SET_FORM_SHIFT_START_TIME,
SET_FORM_SHIFT_DURATION,
SET_CLEAR_CSHIFT_STATE
} from "../constants/cShift.constants";
@ -14,7 +16,9 @@ const initialState = {
cShiftRequestError: "",
cShiftRequestSuccess: "",
employeeUUID: "",
priceUUID: ""
priceUUID: "",
startTime: null,
duration: 60
};
function cShiftReducer(state = initialState, action) {
@ -54,6 +58,16 @@ function cShiftReducer(state = initialState, action) {
...state,
priceUUID: action.data
};
case SET_FORM_SHIFT_START_TIME:
return {
...state,
startTime: action.data
};
case SET_FORM_SHIFT_DURATION:
return {
...state,
duration: action.data
};
case SET_CLEAR_CSHIFT_STATE:
return {
...initialState

View File

@ -4587,6 +4587,10 @@ mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.1, mkdirp@~0.5.0, mkdi
dependencies:
minimist "0.0.8"
moment@^2.22.1:
version "2.22.1"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.1.tgz#529a2e9bf973f259c9643d237fda84de3a26e8ad"
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
@ -5117,6 +5121,10 @@ pluralize@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777"
popper.js@^1.14.1:
version "1.14.3"
resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.14.3.tgz#1438f98d046acf7b4d78cd502bf418ac64d4f095"
portfinder@^1.0.9:
version "1.0.13"
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.13.tgz#bb32ecd87c27104ae6ee44b5a3ccbf0ebb1aede9"
@ -5471,7 +5479,7 @@ promise@^7.1.1:
dependencies:
asap "~2.0.3"
prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.6.0:
prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.6.0, prop-types@^15.6.1:
version "15.6.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.1.tgz#36644453564255ddda391191fb3a125cbdf654ca"
dependencies:
@ -5609,6 +5617,15 @@ react-color@^2.13.8:
reactcss "^1.2.0"
tinycolor2 "^1.4.1"
react-datepicker@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/react-datepicker/-/react-datepicker-1.4.1.tgz#ee171b71d9853e56f9eece5fc3186402f4648683"
dependencies:
classnames "^2.2.5"
prop-types "^15.6.0"
react-onclickoutside "^6.7.1"
react-popper "^0.9.1"
react-dev-utils@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-5.0.1.tgz#1f396e161fe44b595db1b186a40067289bf06613"
@ -5645,6 +5662,17 @@ react-error-overlay@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-4.0.0.tgz#d198408a85b4070937a98667f500c832f86bd5d4"
react-onclickoutside@^6.7.1:
version "6.7.1"
resolved "https://registry.yarnpkg.com/react-onclickoutside/-/react-onclickoutside-6.7.1.tgz#6a5b5b8b4eae6b776259712c89c8a2b36b17be93"
react-popper@^0.9.1:
version "0.9.5"
resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-0.9.5.tgz#02a24ef3eec33af9e54e8358ab70eb0e331edd05"
dependencies:
popper.js "^1.14.1"
prop-types "^15.6.1"
react-redux@^5.0.6:
version "5.0.7"
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.0.7.tgz#0dc1076d9afb4670f993ffaef44b8f8c1155a4c8"