From 0c8defd469b41939f508a64abeccc8a7ca52a708 Mon Sep 17 00:00:00 2001 From: Alexander Wong Date: Wed, 18 Apr 2018 16:50:02 -0600 Subject: [PATCH] added functional duration/time selector --- package.json | 2 + src/actions/cShift/reducer.actions.js | 18 +++- .../User/Client/ClientAddShiftForm.jsx | 99 ++++++++++++++----- .../User/Client/shiftStartTimeOverrides.css | 48 +++++++++ src/constants/cShift.constants.js | 2 + src/reducers/cShiftReducer.js | 16 ++- yarn.lock | 30 +++++- 7 files changed, 190 insertions(+), 25 deletions(-) create mode 100644 src/components/User/Client/shiftStartTimeOverrides.css diff --git a/package.json b/package.json index f56a286..45cc569 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/actions/cShift/reducer.actions.js b/src/actions/cShift/reducer.actions.js index ae02c81..8cf090f 100644 --- a/src/actions/cShift/reducer.actions.js +++ b/src/actions/cShift/reducer.actions.js @@ -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 diff --git a/src/components/User/Client/ClientAddShiftForm.jsx b/src/components/User/Client/ClientAddShiftForm.jsx index 5634805..68c811a 100644 --- a/src/components/User/Client/ClientAddShiftForm.jsx +++ b/src/components/User/Client/ClientAddShiftForm.jsx @@ -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 ; @@ -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 }) => (
Schedule a Shift
@@ -117,40 +160,52 @@ const ClientAddShiftFormView = ({ - - + + - - + + diff --git a/src/components/User/Client/shiftStartTimeOverrides.css b/src/components/User/Client/shiftStartTimeOverrides.css new file mode 100644 index 0000000..a0a5bbc --- /dev/null +++ b/src/components/User/Client/shiftStartTimeOverrides.css @@ -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%; +} diff --git a/src/constants/cShift.constants.js b/src/constants/cShift.constants.js index 9a9884c..69e185c 100644 --- a/src/constants/cShift.constants.js +++ b/src/constants/cShift.constants.js @@ -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"; diff --git a/src/reducers/cShiftReducer.js b/src/reducers/cShiftReducer.js index 50f43ba..3425df1 100644 --- a/src/reducers/cShiftReducer.js +++ b/src/reducers/cShiftReducer.js @@ -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 diff --git a/yarn.lock b/yarn.lock index d74149b..98c0723 100644 --- a/yarn.lock +++ b/yarn.lock @@ -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"