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
}) => (
@@ -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"