From 0fc6ac31f563a8bc4ee6c094a16616de9a633a8f Mon Sep 17 00:00:00 2001 From: Alexander Wong Date: Sun, 22 Apr 2018 23:04:09 -0600 Subject: [PATCH] added pShift scaffolding --- src/actions/pShift/reducer.actions.js | 49 ++++++ src/actions/pShift/saga.actions.js | 8 + src/api/pShift.api.js | 5 + src/components/App.jsx | 5 + src/components/Navbar.jsx | 5 + src/components/User/Client/ClientShifts.jsx | 2 +- .../User/Provider/ProviderShifts.jsx | 166 ++++++++++++++++++ .../User/Provider/ProviderShiftsShared.js | 42 +++++ src/constants/pShift.constants.js | 10 ++ src/reducers/index.js | 4 +- src/reducers/pShiftReducer.js | 52 ++++++ src/sagas/index.js | 3 + src/sagas/pShift.sagas.js | 30 ++++ 13 files changed, 379 insertions(+), 2 deletions(-) create mode 100644 src/actions/pShift/reducer.actions.js create mode 100644 src/actions/pShift/saga.actions.js create mode 100644 src/api/pShift.api.js create mode 100644 src/components/User/Provider/ProviderShifts.jsx create mode 100644 src/components/User/Provider/ProviderShiftsShared.js create mode 100644 src/constants/pShift.constants.js create mode 100644 src/reducers/pShiftReducer.js create mode 100644 src/sagas/pShift.sagas.js diff --git a/src/actions/pShift/reducer.actions.js b/src/actions/pShift/reducer.actions.js new file mode 100644 index 0000000..59271a6 --- /dev/null +++ b/src/actions/pShift/reducer.actions.js @@ -0,0 +1,49 @@ +import { + IS_SENDING_PSHIFT_REQUEST, + SET_PSHIFT_REQUEST_SUCCESS, + SET_PSHIFT_REQUEST_ERROR, + CLEAR_PSHIFT_REQUEST_ERROR, + CLEAR_PSHIFT_REQUEST_SUCCESS, + SET_CLEAR_PSHIFT_STATE +} from "../../constants/pShift.constants"; +import { parseError } from "../common.actions"; + +export function isSendingPShiftRequest(sendingRequest) { + return { + type: IS_SENDING_PSHIFT_REQUEST, + data: sendingRequest + }; +} + +export function setPShiftRequestSuccess(response) { + return { + type: SET_PSHIFT_REQUEST_SUCCESS, + data: response.detail || response + }; +} + +export function setPShiftRequestError(exception) { + let error = parseError(exception); + return { + type: SET_PSHIFT_REQUEST_ERROR, + data: error + }; +} + +export function clearPShiftRequestError() { + return { + type: CLEAR_PSHIFT_REQUEST_ERROR + }; +} + +export function clearPShiftRequestSuccess() { + return { + type: CLEAR_PSHIFT_REQUEST_SUCCESS + }; +} + +export function setClearPShiftState() { + return { + type: SET_CLEAR_PSHIFT_STATE + }; +} diff --git a/src/actions/pShift/saga.actions.js b/src/actions/pShift/saga.actions.js new file mode 100644 index 0000000..3f081ac --- /dev/null +++ b/src/actions/pShift/saga.actions.js @@ -0,0 +1,8 @@ +import { GET_PSHIFTS_REQUEST } from "../../constants/pShift.constants"; + +export function getPShiftsRequest(params) { + return { + type: GET_PSHIFTS_REQUEST, + data: params + }; +} diff --git a/src/api/pShift.api.js b/src/api/pShift.api.js new file mode 100644 index 0000000..bbd0a9b --- /dev/null +++ b/src/api/pShift.api.js @@ -0,0 +1,5 @@ +import { get } from "./baseApi"; + +export function getPShifts(params) { + return get("/pshift/", params).then(resp => Promise.resolve(resp)); +} diff --git a/src/components/App.jsx b/src/components/App.jsx index 3165060..0e11d6c 100644 --- a/src/components/App.jsx +++ b/src/components/App.jsx @@ -18,6 +18,7 @@ import ClientShifts from "./User/Client/ClientShifts"; import ClientAddShiftForm from "./User/Client/ClientAddShiftForm"; import ClientEditShiftForm from "./User/Client/ClientEditShiftForm"; import ProviderClients from "./User/Provider/ProviderClients"; +import ProviderShifts from "./User/Provider/ProviderShifts"; import CompleteRegistration from "./User/CompleteRegistration"; import EditProfile from "./User/EditProfile"; import Profile from "./User/Profile"; @@ -101,6 +102,10 @@ class App extends Component { path="/user/profile/provider/clients" component={ProviderClients} /> + diff --git a/src/components/Navbar.jsx b/src/components/Navbar.jsx index 62475c3..750233f 100644 --- a/src/components/Navbar.jsx +++ b/src/components/Navbar.jsx @@ -83,6 +83,11 @@ const NavbarView = ({ isAuthenticated, dispatchLogoutRequest, selfUser }) => ( Clients )} + {selfUser.provider && ( + + Shifts + + )} Settings diff --git a/src/components/User/Client/ClientShifts.jsx b/src/components/User/Client/ClientShifts.jsx index e7d7c7d..76cd261 100644 --- a/src/components/User/Client/ClientShifts.jsx +++ b/src/components/User/Client/ClientShifts.jsx @@ -154,7 +154,7 @@ const ClientShiftsView = ({ "/hour"} {result.description} - {JSON.stringify(result, null, 2)} + {/* {JSON.stringify(result, null, 2)} */} {employee.provider.email} diff --git a/src/components/User/Provider/ProviderShifts.jsx b/src/components/User/Provider/ProviderShifts.jsx new file mode 100644 index 0000000..8150180 --- /dev/null +++ b/src/components/User/Provider/ProviderShifts.jsx @@ -0,0 +1,166 @@ +import { utc, ISO_8601, duration } from "moment"; +import React, { Component } from "react"; +import { connect } from "react-redux"; +import { Redirect } from "react-router-dom"; +import { + Container, + Header, + Item, + Pagination, + Loader, + Label +} from "semantic-ui-react"; +import { + getEmployerFromPrice, + getPriceFromPrice +} from "./ProviderShiftsShared"; +import { getPShiftsRequest } from "../../../actions/pShift/saga.actions"; + +class ProviderShifts extends Component { + constructor(props) { + super(props); + this.state = { + page: 1, + pageSize: 10 // client can't control this, but set here just in case + }; + } + + componentWillMount = () => { + this.props.dispatch( + getPShiftsRequest({ + page: this.state.page, + page_size: this.state.pageSize + }) + ); + }; + + handlePaginationChange = (event, { activePage }) => { + this.props.dispatch( + getPShiftsRequest({ + page: activePage, + page_size: this.state.pageSize + }) + ); + this.setState({ page: activePage }); + }; + + render() { + const { + isSendingPShiftRequest, + pShiftRequestSuccess, + selfUser + } = this.props; + const { page, pageSize } = this.state; + if (selfUser.provider) { + return ( + + ); + } else { + return ; + } + } +} + +function mapStateToProps(state) { + return { ...state.pShift, selfUser: state.user.selfUser }; +} + +const ProviderShiftsView = ({ + isSendingPShiftRequest, + pShiftRequestSuccess, + user, + page, + pageSize, + handlePaginationChange +}) => { + const { count = 0, results = [] } = pShiftRequestSuccess; + return ( + +
Shifts
+ {!!isSendingPShiftRequest && } + {!isSendingPShiftRequest && + results.length > 0 && ( + + {results.map(result => { + const employer = getEmployerFromPrice(result.price, user); + const price = getPriceFromPrice(result.price, user); + const workType = price.work_type; + const min = duration( + utc(result.set_end, ISO_8601) - utc(result.set_start, ISO_8601), + "milliseconds" + ).as("minutes"); + let displayText = duration(min, "minutes").humanize(); + if (min % 60) { + displayText = duration( + Math.floor(min / 60), + "hours" + ).humanize(); + displayText += ` and ${duration( + min % 60, + "minutes" + ).humanize()}`; + } + return ( + + + + + + {"At " + + utc(result.set_start, ISO_8601) + .local(false) + .format("dddd, MMMM Do YYYY, h:mm a Z") + + "; for " + + displayText + + "; rate $" + + price.amount + + "/hour"} + + {result.description} + {/* {JSON.stringify(result, null, 2)} */} + +
+ {employer.client.email} + +
+ + + ); + })} + + )} +
+ +
+ + ); +}; + +export default connect(mapStateToProps)(ProviderShifts); diff --git a/src/components/User/Provider/ProviderShiftsShared.js b/src/components/User/Provider/ProviderShiftsShared.js new file mode 100644 index 0000000..2c2dea7 --- /dev/null +++ b/src/components/User/Provider/ProviderShiftsShared.js @@ -0,0 +1,42 @@ +export const getEmployerFromPrice = (priceUUID, selfUser) => { + const employers = + selfUser && selfUser.provider && selfUser.provider.employers; + let matchEmployer = null; + employers.forEach(employer => { + const priceMatch = employer.prices.filter(price => { + return price.uuid === priceUUID; + }); + if (priceMatch.length > 0) { + matchEmployer = employer; + } + }); + return matchEmployer; +}; + +export const getWorkTypeFromPrice = (priceUUID, selfUser) => { + const employers = + selfUser && selfUser.provider && selfUser.provider.employers; + let matchWorkType = null; + employers.forEach(employer => { + employer.prices.forEach(price => { + if (price.uuid === priceUUID) { + matchWorkType = price.work_type; + } + }); + }); + return matchWorkType; +}; + +export const getPriceFromPrice = (priceUUID, selfUser) => { + const employers = + selfUser && selfUser.provider && selfUser.provider.employers; + let matchPrice = null; + employers.forEach(employer => { + employer.prices.forEach(price => { + if (price.uuid === priceUUID) { + matchPrice = price; + } + }); + }); + return matchPrice; +}; diff --git a/src/constants/pShift.constants.js b/src/constants/pShift.constants.js new file mode 100644 index 0000000..c4de2a3 --- /dev/null +++ b/src/constants/pShift.constants.js @@ -0,0 +1,10 @@ +// Reducer PShift Action Constants +export const IS_SENDING_PSHIFT_REQUEST = "IS_SENDING_PSHIFT_REQUEST"; +export const SET_PSHIFT_REQUEST_ERROR = "SET_PSHIFT_REQUEST_ERROR"; +export const CLEAR_PSHIFT_REQUEST_ERROR = "CLEAR_PSHIFT_REQUEST_ERROR"; +export const SET_PSHIFT_REQUEST_SUCCESS = "SET_PSHIFT_REQUEST_SUCCESS"; +export const CLEAR_PSHIFT_REQUEST_SUCCESS = "CLEAR_PSHIFT_REQUEST_SUCCESS"; +export const SET_CLEAR_PSHIFT_STATE = "SET_CLEAR_PSHIFT_STATE"; + +// Saga PShift Action Constants +export const GET_PSHIFTS_REQUEST = "GET_PSHIFTS_REQUEST"; diff --git a/src/reducers/index.js b/src/reducers/index.js index 6d9e6ba..2b29b15 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -6,6 +6,7 @@ import employeeReducer from "./employeeReducer"; // import employerReducer from "./employerReducer"; // unused import priceReducer from "./priceReducer"; import cShiftReducer from "./cShiftReducer"; +import pShiftReducer from "./pShiftReducer"; const reducer = combineReducers({ auth: authReducer, @@ -14,7 +15,8 @@ const reducer = combineReducers({ employee: employeeReducer, // employer: employerReducer // unused price: priceReducer, - cShift: cShiftReducer + cShift: cShiftReducer, + pShift: pShiftReducer }); export default reducer; diff --git a/src/reducers/pShiftReducer.js b/src/reducers/pShiftReducer.js new file mode 100644 index 0000000..82829a4 --- /dev/null +++ b/src/reducers/pShiftReducer.js @@ -0,0 +1,52 @@ +import { + IS_SENDING_PSHIFT_REQUEST, + SET_PSHIFT_REQUEST_ERROR, + SET_PSHIFT_REQUEST_SUCCESS, + CLEAR_PSHIFT_REQUEST_ERROR, + CLEAR_PSHIFT_REQUEST_SUCCESS, + SET_CLEAR_PSHIFT_STATE +} from "../constants/pShift.constants"; + +const initialState = { + isSendingPShiftRequest: false, + pShiftRequestError: "", + pShiftRequestSuccess: "" +}; + +function pShiftReducer(state = initialState, action) { + switch (action.type) { + case IS_SENDING_PSHIFT_REQUEST: + return { + ...state, + isSendingPShiftRequest: action.data + }; + case SET_PSHIFT_REQUEST_ERROR: + return { + ...state, + pShiftRequestError: action.data + }; + case CLEAR_PSHIFT_REQUEST_ERROR: + return { + ...state, + pShiftRequestError: "" + }; + case SET_PSHIFT_REQUEST_SUCCESS: + return { + ...state, + pShiftRequestSuccess: action.data + }; + case CLEAR_PSHIFT_REQUEST_SUCCESS: + return { + ...state, + pShiftRequestSuccess: "" + }; + case SET_CLEAR_PSHIFT_STATE: + return { + ...initialState + }; + default: + return { ...state }; + } +} + +export default pShiftReducer; diff --git a/src/sagas/index.js b/src/sagas/index.js index 0a66f68..f1404ac 100644 --- a/src/sagas/index.js +++ b/src/sagas/index.js @@ -83,6 +83,8 @@ import { editCShiftFlow, deleteCShiftFlow } from "./cShift.sagas"; +import { GET_PSHIFTS_REQUEST } from "../constants/pShift.constants"; +import { getPShiftsFlow } from "./pShift.sagas"; export default function* rootSaga() { yield takeLatest(SEND_REGISTER_REQUEST, registerUserFlow); @@ -115,4 +117,5 @@ export default function* rootSaga() { yield takeLatest(GET_CSHIFT_REQUEST, getCShiftFlow); yield takeLatest(EDIT_CSHIFT_REQUEST, editCShiftFlow); yield takeLatest(DELETE_CSHIFT_REQUEST, deleteCShiftFlow); + yield takeLatest(GET_PSHIFTS_REQUEST, getPShiftsFlow); } diff --git a/src/sagas/pShift.sagas.js b/src/sagas/pShift.sagas.js new file mode 100644 index 0000000..ac38391 --- /dev/null +++ b/src/sagas/pShift.sagas.js @@ -0,0 +1,30 @@ +import { effects } from "redux-saga"; +import { + isSendingPShiftRequest, + setPShiftRequestError, + setPShiftRequestSuccess, + clearPShiftRequestError, + clearPShiftRequestSuccess +} from "../actions/pShift/reducer.actions"; +import { getPShifts } from "../api/pShift.api"; + +function* getPShiftsCall(params) { + yield effects.put(isSendingPShiftRequest(true)); + try { + return yield effects.call(getPShifts, params); + } catch (exception) { + yield effects.put(setPShiftRequestError(exception)); + return false; + } finally { + yield effects.put(isSendingPShiftRequest(false)); + } +} + +export function* getPShiftsFlow(request) { + yield effects.put(clearPShiftRequestSuccess()); + yield effects.put(clearPShiftRequestError()); + const wasSuccessful = yield effects.call(getPShiftsCall, request.data); + if (wasSuccessful) { + yield effects.put(setPShiftRequestSuccess(wasSuccessful)); + } +}