added functional duration/time selector
This commit is contained in:
parent
99dc3a9615
commit
0c8defd469
|
@ -5,8 +5,10 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^0.18.0",
|
"axios": "^0.18.0",
|
||||||
"localStorage": "^1.0.3",
|
"localStorage": "^1.0.3",
|
||||||
|
"moment": "^2.22.1",
|
||||||
"react": "^16.2.0",
|
"react": "^16.2.0",
|
||||||
"react-color": "^2.13.8",
|
"react-color": "^2.13.8",
|
||||||
|
"react-datepicker": "^1.4.1",
|
||||||
"react-dom": "^16.2.0",
|
"react-dom": "^16.2.0",
|
||||||
"react-redux": "^5.0.6",
|
"react-redux": "^5.0.6",
|
||||||
"react-router": "^4.2.0",
|
"react-router": "^4.2.0",
|
||||||
|
|
|
@ -6,7 +6,9 @@ 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_CLEAR_CSHIFT_STATE,
|
||||||
|
SET_FORM_SHIFT_START_TIME,
|
||||||
|
SET_FORM_SHIFT_DURATION
|
||||||
} from "../../constants/cShift.constants";
|
} from "../../constants/cShift.constants";
|
||||||
import { parseError } from "../common.actions";
|
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() {
|
export function setClearCshiftState() {
|
||||||
return {
|
return {
|
||||||
type: SET_CLEAR_CSHIFT_STATE
|
type: SET_CLEAR_CSHIFT_STATE
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
import { duration } from "moment";
|
||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
|
import DatePicker from "react-datepicker";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { Redirect } from "react-router-dom";
|
import { Redirect } from "react-router-dom";
|
||||||
import {
|
import {
|
||||||
|
@ -6,24 +8,38 @@ import {
|
||||||
Dropdown,
|
Dropdown,
|
||||||
Form,
|
Form,
|
||||||
Header,
|
Header,
|
||||||
Input,
|
|
||||||
Label,
|
Label,
|
||||||
TextArea
|
TextArea
|
||||||
} from "semantic-ui-react";
|
} from "semantic-ui-react";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
clearCShiftRequestError,
|
|
||||||
clearCShiftRequestSuccess,
|
|
||||||
setFormEmployeeUUID,
|
setFormEmployeeUUID,
|
||||||
setFormPriceUUID
|
setFormPriceUUID,
|
||||||
|
setFormShiftStartTime,
|
||||||
|
setFormShiftDuration,
|
||||||
|
setClearCshiftState
|
||||||
} from "../../../actions/cShift/reducer.actions";
|
} 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 {
|
class ClientAddShiftForm extends Component {
|
||||||
componentWillMount = () => {
|
componentWillMount = () => {
|
||||||
this.props.dispatch(clearCShiftRequestError());
|
this.props.dispatch(setClearCshiftState());
|
||||||
this.props.dispatch(clearCShiftRequestSuccess());
|
|
||||||
this.props.dispatch(setFormEmployeeUUID(""));
|
|
||||||
this.props.dispatch(setFormPriceUUID(""));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
changeSelectedEmployee = (e, { value }) => {
|
changeSelectedEmployee = (e, { value }) => {
|
||||||
|
@ -37,8 +53,26 @@ class ClientAddShiftForm extends Component {
|
||||||
this.props.dispatch(setFormPriceUUID(value));
|
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() {
|
render() {
|
||||||
const { selfUser, employeeUUID, priceUUID } = this.props;
|
const {
|
||||||
|
selfUser,
|
||||||
|
employeeUUID,
|
||||||
|
priceUUID,
|
||||||
|
startTime,
|
||||||
|
duration
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
if (!selfUser.client) {
|
if (!selfUser.client) {
|
||||||
return <Redirect to="/" />;
|
return <Redirect to="/" />;
|
||||||
|
@ -51,6 +85,7 @@ class ClientAddShiftForm extends Component {
|
||||||
value: uuid,
|
value: uuid,
|
||||||
text: provider.email
|
text: provider.email
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const priceChoices = [];
|
const priceChoices = [];
|
||||||
if (employeeUUID) {
|
if (employeeUUID) {
|
||||||
const employee = selfUser.client.employees.find(emp => {
|
const employee = selfUser.client.employees.find(emp => {
|
||||||
|
@ -90,8 +125,12 @@ class ClientAddShiftForm extends Component {
|
||||||
priceChoices={priceChoices}
|
priceChoices={priceChoices}
|
||||||
employeeUUID={employeeUUID}
|
employeeUUID={employeeUUID}
|
||||||
priceUUID={priceUUID}
|
priceUUID={priceUUID}
|
||||||
|
startTime={startTime}
|
||||||
|
duration={duration}
|
||||||
changeSelectedEmployee={this.changeSelectedEmployee}
|
changeSelectedEmployee={this.changeSelectedEmployee}
|
||||||
changeSelectedPrice={this.changeSelectedPrice}
|
changeSelectedPrice={this.changeSelectedPrice}
|
||||||
|
changeShiftStartTime={this.changeShiftStartTime}
|
||||||
|
changeShiftDuration={this.changeShiftDuration}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -107,8 +146,12 @@ const ClientAddShiftFormView = ({
|
||||||
priceChoices,
|
priceChoices,
|
||||||
employeeUUID,
|
employeeUUID,
|
||||||
priceUUID,
|
priceUUID,
|
||||||
|
startTime,
|
||||||
|
duration,
|
||||||
changeSelectedEmployee,
|
changeSelectedEmployee,
|
||||||
changeSelectedPrice
|
changeSelectedPrice,
|
||||||
|
changeShiftStartTime,
|
||||||
|
changeShiftDuration
|
||||||
}) => (
|
}) => (
|
||||||
<Container>
|
<Container>
|
||||||
<Header>Schedule a Shift</Header>
|
<Header>Schedule a Shift</Header>
|
||||||
|
@ -117,40 +160,52 @@ const ClientAddShiftFormView = ({
|
||||||
<Form.Field>
|
<Form.Field>
|
||||||
<label>Employee</label>
|
<label>Employee</label>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
|
onChange={changeSelectedEmployee}
|
||||||
|
options={employeeChoices}
|
||||||
placeholder="Select employee"
|
placeholder="Select employee"
|
||||||
openOnFocus
|
|
||||||
closeOnBlur
|
|
||||||
selection
|
selection
|
||||||
fluid
|
fluid
|
||||||
search
|
search
|
||||||
options={employeeChoices}
|
|
||||||
noResultsMessage="No approved employees found."
|
noResultsMessage="No approved employees found."
|
||||||
onChange={changeSelectedEmployee}
|
|
||||||
value={employeeUUID}
|
value={employeeUUID}
|
||||||
/>
|
/>
|
||||||
</Form.Field>
|
</Form.Field>
|
||||||
<Form.Field>
|
<Form.Field>
|
||||||
<label>Price</label>
|
<label>Price</label>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
|
onChange={changeSelectedPrice}
|
||||||
|
options={priceChoices}
|
||||||
placeholder="Select price"
|
placeholder="Select price"
|
||||||
openOnFocus
|
|
||||||
closeOnBlur
|
|
||||||
selection
|
selection
|
||||||
fluid
|
fluid
|
||||||
search
|
search
|
||||||
options={priceChoices}
|
|
||||||
noResultsMessage="No prices for given employee."
|
noResultsMessage="No prices for given employee."
|
||||||
onChange={changeSelectedPrice}
|
|
||||||
value={priceUUID}
|
value={priceUUID}
|
||||||
/>
|
/>
|
||||||
</Form.Field>
|
</Form.Field>
|
||||||
<Form.Field>
|
<Form.Field>
|
||||||
<label>Time</label>
|
<label>Shift Start Time</label>
|
||||||
<Input placeholder="Time" type="text" />
|
<DatePicker
|
||||||
|
selected={startTime}
|
||||||
|
onChange={changeShiftStartTime}
|
||||||
|
showTimeSelect
|
||||||
|
showTimeSelectOnly
|
||||||
|
timeIntervals={30}
|
||||||
|
dateFormat="LT Z"
|
||||||
|
timeFormat="hh:mm"
|
||||||
|
placeholderText="Select shift start time"
|
||||||
|
/>
|
||||||
</Form.Field>
|
</Form.Field>
|
||||||
<Form.Field>
|
<Form.Field>
|
||||||
<label>Duration</label>
|
<label>Shift Duration</label>
|
||||||
<Input placeholder="Duration" type="text" />
|
<Dropdown
|
||||||
|
onChange={changeShiftDuration}
|
||||||
|
options={CShiftDurationOptions}
|
||||||
|
placeholder="Select duration"
|
||||||
|
selection
|
||||||
|
fluid
|
||||||
|
value={duration}
|
||||||
|
/>
|
||||||
</Form.Field>
|
</Form.Field>
|
||||||
</Form.Group>
|
</Form.Group>
|
||||||
<Form.Field>
|
<Form.Field>
|
||||||
|
|
48
src/components/User/Client/shiftStartTimeOverrides.css
Normal file
48
src/components/User/Client/shiftStartTimeOverrides.css
Normal 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%;
|
||||||
|
}
|
|
@ -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 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_DURATION = "SET_FORM_SHIFT_DURATION";
|
||||||
|
|
||||||
export const SET_CLEAR_CSHIFT_STATE = "SET_CLEAR_CSHIFT_STATE";
|
export const SET_CLEAR_CSHIFT_STATE = "SET_CLEAR_CSHIFT_STATE";
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@ 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_FORM_SHIFT_START_TIME,
|
||||||
|
SET_FORM_SHIFT_DURATION,
|
||||||
SET_CLEAR_CSHIFT_STATE
|
SET_CLEAR_CSHIFT_STATE
|
||||||
} from "../constants/cShift.constants";
|
} from "../constants/cShift.constants";
|
||||||
|
|
||||||
|
@ -14,7 +16,9 @@ const initialState = {
|
||||||
cShiftRequestError: "",
|
cShiftRequestError: "",
|
||||||
cShiftRequestSuccess: "",
|
cShiftRequestSuccess: "",
|
||||||
employeeUUID: "",
|
employeeUUID: "",
|
||||||
priceUUID: ""
|
priceUUID: "",
|
||||||
|
startTime: null,
|
||||||
|
duration: 60
|
||||||
};
|
};
|
||||||
|
|
||||||
function cShiftReducer(state = initialState, action) {
|
function cShiftReducer(state = initialState, action) {
|
||||||
|
@ -54,6 +58,16 @@ function cShiftReducer(state = initialState, action) {
|
||||||
...state,
|
...state,
|
||||||
priceUUID: action.data
|
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:
|
case SET_CLEAR_CSHIFT_STATE:
|
||||||
return {
|
return {
|
||||||
...initialState
|
...initialState
|
||||||
|
|
30
yarn.lock
30
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:
|
dependencies:
|
||||||
minimist "0.0.8"
|
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:
|
ms@2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||||
|
@ -5117,6 +5121,10 @@ pluralize@^7.0.0:
|
||||||
version "7.0.0"
|
version "7.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777"
|
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:
|
portfinder@^1.0.9:
|
||||||
version "1.0.13"
|
version "1.0.13"
|
||||||
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.13.tgz#bb32ecd87c27104ae6ee44b5a3ccbf0ebb1aede9"
|
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.13.tgz#bb32ecd87c27104ae6ee44b5a3ccbf0ebb1aede9"
|
||||||
|
@ -5471,7 +5479,7 @@ promise@^7.1.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
asap "~2.0.3"
|
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"
|
version "15.6.1"
|
||||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.1.tgz#36644453564255ddda391191fb3a125cbdf654ca"
|
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.1.tgz#36644453564255ddda391191fb3a125cbdf654ca"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -5609,6 +5617,15 @@ react-color@^2.13.8:
|
||||||
reactcss "^1.2.0"
|
reactcss "^1.2.0"
|
||||||
tinycolor2 "^1.4.1"
|
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:
|
react-dev-utils@^5.0.1:
|
||||||
version "5.0.1"
|
version "5.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-5.0.1.tgz#1f396e161fe44b595db1b186a40067289bf06613"
|
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"
|
version "4.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-4.0.0.tgz#d198408a85b4070937a98667f500c832f86bd5d4"
|
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:
|
react-redux@^5.0.6:
|
||||||
version "5.0.7"
|
version "5.0.7"
|
||||||
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.0.7.tgz#0dc1076d9afb4670f993ffaef44b8f8c1155a4c8"
|
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.0.7.tgz#0dc1076d9afb4670f993ffaef44b8f8c1155a4c8"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user